crypto/prfs/prf.c crypto/prfs/mac_prf.c crypto/pkcs5.c \
crypto/rngs/rng.c crypto/prf_plus.c crypto/signers/signer.c \
crypto/signers/mac_signer.c crypto/crypto_factory.c crypto/crypto_tester.c \
-crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \
+crypto/diffie_hellman.c crypto/aead.c crypto/transform.c crypto/qske_mechanism.c \
crypto/iv/iv_gen.c crypto/iv/iv_gen_rand.c crypto/iv/iv_gen_seq.c \
crypto/iv/iv_gen_null.c \
crypto/xofs/xof.c crypto/xofs/xof_bitspender.c \
crypto/prfs/prf.c crypto/prfs/mac_prf.c crypto/pkcs5.c \
crypto/rngs/rng.c crypto/prf_plus.c crypto/signers/signer.c \
crypto/signers/mac_signer.c crypto/crypto_factory.c crypto/crypto_tester.c \
-crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \
+crypto/diffie_hellman.c crypto/aead.c crypto/transform.c crypto/qske_mechanism.c \
crypto/iv/iv_gen.c crypto/iv/iv_gen_rand.c crypto/iv/iv_gen_seq.c \
crypto/iv/iv_gen_null.c \
crypto/xofs/xof.c crypto/xofs/xof_bitspender.c \
asn1/asn1.h asn1/asn1_parser.h asn1/oid.h bio/bio_reader.h bio/bio_writer.h \
collections/blocking_queue.h collections/enumerator.h collections/hashtable.h \
collections/linked_list.h collections/array.h collections/dictionary.h \
-crypto/crypters/crypter.h crypto/hashers/hasher.h \
+crypto/crypters/crypter.h crypto/hashers/hasher.h crypto/qske_mechanism.h \
crypto/hashers/hash_algorithm_set.h crypto/mac.h crypto/proposal/proposal.h \
crypto/proposal/proposal_keywords.h crypto/proposal/proposal_keywords_static.h \
crypto/prfs/prf.h crypto/prfs/mac_prf.h crypto/rngs/rng.h crypto/nonce_gen.h \
rng_constructor_t create_rng;
nonce_gen_constructor_t create_nonce_gen;
dh_constructor_t create_dh;
+ qske_constructor_t create_qske;
void *create;
};
};
*/
linked_list_t *dhs;
+ /**
+ * registered QSKE mechanisms, as entry_t
+ */
+ linked_list_t *qskes;
+
/**
* test manager to test crypto algorithms
*/
return diffie_hellman;
}
+METHOD(crypto_factory_t, create_qske, qske_t*,
+ private_crypto_factory_t *this, qske_mechanism_t mechanism)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+ qske_t *qske = NULL;
+
+ this->lock->read_lock(this->lock);
+ enumerator = this->qskes->create_enumerator(this->qskes);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->algo == mechanism)
+ {
+ if (this->test_on_create &&
+ !this->tester->test_qske(this->tester, mechanism,
+ entry->create_qske, NULL, default_plugin_name))
+ {
+ continue;
+ }
+ qske = entry->create_qske(mechanism);
+ if (qske)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+ return qske;
+}
+
/**
* Insert an algorithm entry to a list
*
this->lock->unlock(this->lock);
}
+METHOD(crypto_factory_t, add_qske, bool,
+ private_crypto_factory_t *this, qske_mechanism_t mechanism,
+ const char *plugin_name, qske_constructor_t create)
+{
+ u_int speed = 0;
+
+ if (!this->test_on_add ||
+ this->tester->test_qske(this->tester, mechanism, create,
+ this->bench ? &speed : NULL, plugin_name))
+ {
+ add_entry(this, this->qskes, mechanism, plugin_name, 0, create);
+ return TRUE;
+ }
+ this->test_failures++;
+ return FALSE;
+}
+
+METHOD(crypto_factory_t, remove_qske, void,
+ private_crypto_factory_t *this, qske_constructor_t create)
+{
+ entry_t *entry;
+ enumerator_t *enumerator;
+
+ this->lock->write_lock(this->lock);
+ enumerator = this->qskes->create_enumerator(this->qskes);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->create_qske == create)
+ {
+ this->qskes->remove_at(this->qskes, enumerator);
+ free(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+}
+
CALLBACK(entry_match, bool,
entry_t *a, va_list args)
{
return create_enumerator(this, this->dhs, dh_filter);
}
+CALLBACK(qske_filter, bool,
+ void *n, enumerator_t *orig, va_list args)
+{
+ entry_t *entry;
+ qske_mechanism_t *algo;
+ const char **plugin_name;
+
+ VA_ARGS_VGET(args, algo, plugin_name);
+
+ if (orig->enumerate(orig, &entry))
+ {
+ *algo = entry->algo;
+ *plugin_name = entry->plugin_name;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+METHOD(crypto_factory_t, create_qske_enumerator, enumerator_t*,
+ private_crypto_factory_t *this)
+{
+ return create_enumerator(this, this->qskes, qske_filter);
+}
+
CALLBACK(rng_filter, bool,
void *n, enumerator_t *orig, va_list args)
{
return this->tester->add_rng_vector(this->tester, vector);
case DIFFIE_HELLMAN_GROUP:
return this->tester->add_dh_vector(this->tester, vector);
+ case QSKE_MECHANISM:
+ return this->tester->add_qske_vector(this->tester, vector);
default:
DBG1(DBG_LIB, "%N test vectors not supported, ignored",
transform_type_names, type);
*valid = this->tester->test_dh(this->tester, entry->algo,
entry->create_dh, NULL, entry->plugin_name);
break;
+ case QSKE_MECHANISM:
+ *valid = this->tester->test_qske(this->tester, entry->algo,
+ entry->create_qske, NULL, entry->plugin_name);
+ break;
default:
return FALSE;
}
case DIFFIE_HELLMAN_GROUP:
inner = this->dhs->create_enumerator(this->dhs);
break;
+ case QSKE_MECHANISM:
+ inner = this->qskes->create_enumerator(this->qskes);
+ break;
default:
this->lock->unlock(this->lock);
return enumerator_create_empty();
this->rngs->destroy(this->rngs);
this->nonce_gens->destroy(this->nonce_gens);
this->dhs->destroy(this->dhs);
+ this->qskes->destroy(this->qskes);
this->tester->destroy(this->tester);
this->lock->destroy(this->lock);
free(this);
.create_rng = _create_rng,
.create_nonce_gen = _create_nonce_gen,
.create_dh = _create_dh,
+ .create_qske = _create_qske,
.add_crypter = _add_crypter,
.remove_crypter = _remove_crypter,
.add_aead = _add_aead,
.remove_nonce_gen = _remove_nonce_gen,
.add_dh = _add_dh,
.remove_dh = _remove_dh,
+ .add_qske = _add_qske,
+ .remove_qske = _remove_qske,
.create_crypter_enumerator = _create_crypter_enumerator,
.create_aead_enumerator = _create_aead_enumerator,
.create_signer_enumerator = _create_signer_enumerator,
.create_prf_enumerator = _create_prf_enumerator,
.create_xof_enumerator = _create_xof_enumerator,
.create_dh_enumerator = _create_dh_enumerator,
+ .create_qske_enumerator = _create_qske_enumerator,
.create_rng_enumerator = _create_rng_enumerator,
.create_nonce_gen_enumerator = _create_nonce_gen_enumerator,
.add_test_vector = _add_test_vector,
.rngs = linked_list_create(),
.nonce_gens = linked_list_create(),
.dhs = linked_list_create(),
+ .qskes = linked_list_create(),
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
.tester = crypto_tester_create(),
.test_on_add = lib->settings->get_bool(lib->settings,
#include <crypto/xofs/xof.h>
#include <crypto/nonce_gen.h>
#include <crypto/diffie_hellman.h>
+#include <crypto/qske_mechanism.h>
#include <crypto/transform.h>
#define CRYPTO_MAX_ALG_LINE 120 /* characters */
*/
typedef diffie_hellman_t* (*dh_constructor_t)(diffie_hellman_group_t group, ...);
+/**
+ * Constructor function for QSKE mechanisms
+ */
+typedef qske_t* (*qske_constructor_t)();
+
/**
* Handles crypto modules and creates instances.
*/
diffie_hellman_t* (*create_dh)(crypto_factory_t *this,
diffie_hellman_group_t group, ...);
+ /**
+ * Create a QSKE instance.
+ *
+ * @param mechanism QSKE mechanism
+ * @return qske_t instance, NULL if not supported
+ */
+ qske_t* (*create_qske)(crypto_factory_t *this, qske_mechanism_t mechanism);
+
/**
* Register a crypter constructor.
*
*/
void (*remove_dh)(crypto_factory_t *this, dh_constructor_t create);
+ /**
+ * Register a QSKE constructor.
+ *
+ * @param mechanism QSKE mechanism to constructor
+ * @param plugin_name plugin that registered this algorithm
+ * @param create constructor function for that algorithm
+ * @return TRUE if registered, FALSE if test vector failed
+ */
+ bool (*add_qske)(crypto_factory_t *this, qske_mechanism_t mechanism,
+ const char *plugin_name, qske_constructor_t create);
+
+ /**
+ * Unregister a QSKE constructor.
+ *
+ * @param create constructor function to unregister
+ */
+ void (*remove_qske)(crypto_factory_t *this, qske_constructor_t create);
+
/**
* Create an enumerator over all registered crypter algorithms.
*
*/
enumerator_t* (*create_dh_enumerator)(crypto_factory_t *this);
+ /**
+ * Create an enumerator over all registered QSKE mechanisms
+ *
+ * @return enumerator over qske_mechamism_t, plugin
+ */
+ enumerator_t* (*create_qske_enumerator)(crypto_factory_t *this);
+
/**
* Create an enumerator over all registered random generators.
*
*/
linked_list_t *dh;
+ /**
+ * List of Quantum-Safe Key Encapsulation test vectors
+ */
+ linked_list_t *qske;
+
/**
* Is a test vector required to pass a test?
*/
return !failed;
}
+/**
+ * Benchmark a QSKE backend
+ */
+static u_int bench_qske(private_crypto_tester_t *this,
+ qske_mechanism_t mechanism, qske_constructor_t create)
+{
+ qske_t *a, *b;
+ struct timespec start;
+ chunk_t pk, ct, a_ss, b_ss;
+ u_int runs;
+
+ runs = 0;
+ start_timing(&start);
+ while (end_timing(&start) < this->bench_time)
+ {
+ a = create(mechanism);
+ b = create(mechanism);
+ if (!a || !b)
+ {
+ DESTROY_IF(a);
+ DESTROY_IF(b);
+ return 0;
+ }
+ if (a->get_public_key(a, &pk) &&
+ b->set_public_key(b, pk) &&
+ b->get_ciphertext(b, &ct) &&
+ b->get_shared_secret(b, &b_ss) &&
+ a->set_ciphertext(a, ct) &&
+ a->get_shared_secret(b, &a_ss) &&
+ chunk_equals(a_ss, b_ss))
+ {
+ runs++;
+ }
+ chunk_free(&pk);
+ chunk_free(&ct);
+ chunk_free(&a_ss);
+ chunk_free(&b_ss);
+ a->destroy(a);
+ b->destroy(b);
+ }
+ return runs;
+}
+
+METHOD(crypto_tester_t, test_qske, bool,
+ private_crypto_tester_t *this, qske_mechanism_t mechanism,
+ qske_constructor_t create, u_int *speed, const char *plugin_name)
+{
+ enumerator_t *enumerator;
+ chunk_t pk, ct, a_ss, b_ss;
+ qske_test_vector_t *v;
+ bool failed = FALSE;
+ u_int tested = 0;
+
+ enumerator = this->qske->create_enumerator(this->qske);
+ while (enumerator->enumerate(enumerator, &v))
+ {
+ qske_t *a, *b;
+
+ if (v->mechanism != mechanism)
+ {
+ continue;
+ }
+
+ a = create(mechanism);
+ b = create(mechanism);
+ if (!a || !b)
+ {
+ DESTROY_IF(a);
+ DESTROY_IF(b);
+ failed = TRUE;
+ tested++;
+ DBG1(DBG_LIB, "disabled %N[%s]: creating instance failed",
+ qske_mechanism_names, mechanism, plugin_name);
+ break;
+ }
+ failed = TRUE;
+ tested++;
+
+ if (!a->set_nist_drbg_mode(a, TRUE, v->seed))
+ {
+ goto failure;
+ }
+ if (!a->get_public_key(a, &pk) || !chunk_equals(pk, v->pk))
+ {
+ goto failure;
+ }
+ if (!b->set_public_key(b, pk) || !b->get_ciphertext(b, &ct) ||
+ !chunk_equals(ct, v->ct))
+ {
+ goto failure;
+ }
+ if (!a->set_ciphertext(a, ct) || !a->get_shared_secret(a, &a_ss) ||
+ !chunk_equals(a_ss, v->ss))
+ {
+ goto failure;
+ }
+ if (!b->get_shared_secret(b, &b_ss) || !chunk_equals(b_ss, v->ss))
+ {
+ goto failure;
+ }
+ failed = FALSE;
+
+failure:
+ a->set_nist_drbg_mode(a, FALSE, chunk_empty);
+ a->destroy(a);
+ b->destroy(b);
+ chunk_free(&pk);
+ chunk_free(&ct);
+ chunk_free(&a_ss);
+ chunk_free(&b_ss);
+ if (failed)
+ {
+ DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed",
+ qske_mechanism_names, mechanism, plugin_name, get_name(v));
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (!tested)
+ {
+ DBG1(DBG_LIB, "%s %N[%s]: no test vectors found / untestable",
+ this->required ? "disabled" : "enabled ",
+ qske_mechanism_names, mechanism, plugin_name);
+ return !this->required;
+ }
+ if (!failed)
+ {
+ if (speed)
+ {
+ *speed = bench_qske(this, mechanism, create);
+ DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors, %d points",
+ qske_mechanism_names, mechanism, plugin_name, tested, *speed);
+ }
+ else
+ {
+ DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors",
+ qske_mechanism_names, mechanism, plugin_name, tested);
+ }
+ }
+ return !failed;
+}
+
METHOD(crypto_tester_t, add_crypter_vector, void,
private_crypto_tester_t *this, crypter_test_vector_t *vector)
{
this->dh->insert_last(this->dh, vector);
}
+METHOD(crypto_tester_t, add_qske_vector, void,
+ private_crypto_tester_t *this, qske_test_vector_t *vector)
+{
+ this->qske->insert_last(this->qske, vector);
+}
+
METHOD(crypto_tester_t, destroy, void,
private_crypto_tester_t *this)
{
this->xof->destroy(this->xof);
this->rng->destroy(this->rng);
this->dh->destroy(this->dh);
+ this->qske->destroy(this->qske);
free(this);
}
.test_xof = _test_xof,
.test_rng = _test_rng,
.test_dh = _test_dh,
+ .test_qske = _test_qske,
.add_crypter_vector = _add_crypter_vector,
.add_aead_vector = _add_aead_vector,
.add_signer_vector = _add_signer_vector,
.add_xof_vector = _add_xof_vector,
.add_rng_vector = _add_rng_vector,
.add_dh_vector = _add_dh_vector,
+ .add_qske_vector = _add_qske_vector,
.destroy = _destroy,
},
.crypter = linked_list_create(),
.xof = linked_list_create(),
.rng = linked_list_create(),
.dh = linked_list_create(),
+ .qske = linked_list_create(),
.required = lib->settings->get_bool(lib->settings,
"%s.crypto_test.required", FALSE, lib->ns),
typedef struct xof_test_vector_t xof_test_vector_t;
typedef struct rng_test_vector_t rng_test_vector_t;
typedef struct dh_test_vector_t dh_test_vector_t;
+typedef struct qske_test_vector_t qske_test_vector_t;
struct crypter_test_vector_t {
/** encryption algorithm this vector tests */
size_t shared_len;
};
+struct qske_test_vector_t {
+ /** QSKE mechanism to test */
+ qske_mechanism_t mechanism;
+ /** test vector number */
+ int count;
+ /** seed for NIST DRBG */
+ chunk_t seed;
+ /** public key */
+ chunk_t pk;
+ /** ciphertext */
+ chunk_t ct;
+ /*s* shared secret */
+ chunk_t ss;
+};
+
/**
* Cryptographic primitive testing framework.
*/
bool (*test_dh)(crypto_tester_t *this, diffie_hellman_group_t group,
dh_constructor_t create,
u_int *speed, const char *plugin_name);
-
+ /**
+ * Test a Quantum-Safe Key Encapsulation implementation.
+ *
+ * @param mechanism mechanism to test
+ * @param create constructor function for the QSKE backend
+ * @param speed speeed test result, NULL to omit
+ * @return TRUE if test passed
+ */
+ bool (*test_qske)(crypto_tester_t *this, qske_mechanism_t mechanism,
+ qske_constructor_t create,
+ u_int *speed, const char *plugin_name);
/**
* Add a test vector to test a crypter.
*
*/
void (*add_dh_vector)(crypto_tester_t *this, dh_test_vector_t *vector);
+ /**
+ * Add a test vector to test a QSKE backend.
+ *
+ * @param vector pointer to test vector
+ */
+ void (*add_qske_vector)(crypto_tester_t *this, qske_test_vector_t *vector);
+
/**
* Destroy a crypto_tester_t.
*/
integrity_algorithm_t integrity;
pseudo_random_function_t prf;
diffie_hellman_group_t group;
+ qske_mechanism_t mechanism;
const char *plugin_name;
if (aead)
}
enumerator->destroy(enumerator);
+ /* Round 1 adds QSKE mechanisms with at least 128 bit security strength */
+ enumerator = lib->crypto->create_qske_enumerator(lib->crypto);
+ while (enumerator->enumerate(enumerator, &mechanism, &plugin_name))
+ {
+ switch (mechanism)
+ {
+ case QSKE_NEWHOPE:
+ case QSKE_NEWHOPE_L1:
+ case QSKE_NEWHOPE_L5:
+ case QSKE_FRODO_AES_L1:
+ case QSKE_FRODO_AES_L3:
+ case QSKE_FRODO_SHAKE_L1:
+ case QSKE_FRODO_SHAKE_L3:
+ case QSKE_KYBER_L1:
+ case QSKE_KYBER_L3:
+ case QSKE_KYBER_L5:
+ case QSKE_BIKE1_L1:
+ case QSKE_BIKE1_L3:
+ case QSKE_BIKE1_L5:
+ case QSKE_BIKE2_L1:
+ case QSKE_BIKE2_L3:
+ case QSKE_BIKE2_L5:
+ case QSKE_BIKE3_L1:
+ case QSKE_BIKE3_L3:
+ case QSKE_BIKE3_L5:
+ case QSKE_SIKE_L1:
+ case QSKE_SIKE_L3:
+ case QSKE_SABER_L1:
+ case QSKE_SABER_L3:
+ case QSKE_SABER_L5:
+ case QSKE_LIMA_2P_L3:
+ case QSKE_LIMA_2P_L5:
+ case QSKE_LIMA_SP_L1:
+ case QSKE_LIMA_SP_L2:
+ case QSKE_LIMA_SP_L3:
+ case QSKE_LIMA_SP_L5:
+ add_algorithm(this, QSKE_MECHANISM, mechanism, 0);
+ break;
+ default:
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
return TRUE;
}
#include <crypto/crypters/crypter.h>
#include <crypto/signers/signer.h>
#include <crypto/diffie_hellman.h>
+#include <crypto/qske_mechanism.h>
%}
struct proposal_token {
newhope128, DIFFIE_HELLMAN_GROUP, NH_128_BIT, 0
noesn, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0
esn, EXTENDED_SEQUENCE_NUMBERS, EXT_SEQ_NUMBERS, 0
+qskenewhope, QSKE_MECHANISM, QSKE_NEWHOPE, 0
+qskenewhope1, QSKE_MECHANISM, QSKE_NEWHOPE_L1, 0
+qskenewhope5, QSKE_MECHANISM, QSKE_NEWHOPE_L5, 0
+qskefrodoa1, QSKE_MECHANISM, QSKE_FRODO_AES_L1, 0
+qskefrodoa3, QSKE_MECHANISM, QSKE_FRODO_AES_L3, 0
+qskefrodos1, QSKE_MECHANISM, QSKE_FRODO_SHAKE_L1, 0
+qskefrodos3, QSKE_MECHANISM, QSKE_FRODO_SHAKE_L3, 0
+qskekyber1, QSKE_MECHANISM, QSKE_KYBER_L1, 0
+qskekyber3, QSKE_MECHANISM, QSKE_KYBER_L3, 0
+qskekyber5, QSKE_MECHANISM, QSKE_KYBER_L5, 0
+qskebike11, QSKE_MECHANISM, QSKE_BIKE1_L1, 0
+qskebike13, QSKE_MECHANISM, QSKE_BIKE1_L3, 0
+qskebike15, QSKE_MECHANISM, QSKE_BIKE1_L5, 0
+qskebike21, QSKE_MECHANISM, QSKE_BIKE2_L1, 0
+qskebike23, QSKE_MECHANISM, QSKE_BIKE2_L3, 0
+qskebike25, QSKE_MECHANISM, QSKE_BIKE2_L5, 0
+qskebike31, QSKE_MECHANISM, QSKE_BIKE3_L1, 0
+qskebike33, QSKE_MECHANISM, QSKE_BIKE3_L3, 0
+qskebike35, QSKE_MECHANISM, QSKE_BIKE3_L5, 0
+qskesike1, QSKE_MECHANISM, QSKE_SIKE_L1, 0
+qskesike3, QSKE_MECHANISM, QSKE_SIKE_L3, 0
+qskesaber1, QSKE_MECHANISM, QSKE_SABER_L1, 0
+qskesaber3, QSKE_MECHANISM, QSKE_SABER_L3, 0
+qskesaber5, QSKE_MECHANISM, QSKE_SABER_L5, 0
+qskelima2p3, QSKE_MECHANISM, QSKE_LIMA_2P_L3, 0
+qskelima2p5, QSKE_MECHANISM, QSKE_LIMA_2P_L5, 0
+qskelimasp1, QSKE_MECHANISM, QSKE_LIMA_SP_L1, 0
+qskelimasp2, QSKE_MECHANISM, QSKE_LIMA_SP_L2, 0
+qskelimasp3, QSKE_MECHANISM, QSKE_LIMA_SP_L3, 0
+qskelimasp5, QSKE_MECHANISM, QSKE_LIMA_SP_L5, 0
--- /dev/null
+/*
+ * Copyright (C) 2018 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qske_mechanism.h"
+
+ENUM(qske_mechanism_names, QSKE_NONE, QSKE_FRODO,
+ "QSKE_NONE",
+ "QSKE_NEWHOPE",
+ "QSKE_NEWHOPE_L1",
+ "QSKE_NEWHOPE_L5",
+ "QSKE_FRODO_AES_L1",
+ "QSKE_FRODO_AES_L3",
+ "QSKE_FRODO_SHAKE_L1",
+ "QSKE_FRODO_SHAKE_L3",
+ "QSKE_KYBER_L1",
+ "QSKE_KYBER_L3",
+ "QSKE_KYBER_L5",
+ "QSKE_BIKE1_L1",
+ "QSKE_BIKE1_L3",
+ "QSKE_BIKE1_L5",
+ "QSKE_BIKE2_L1",
+ "QSKE_BIKE2_L3",
+ "QSKE_BIKE2_L5",
+ "QSKE_BIKE3_L1",
+ "QSKE_BIKE3_L3",
+ "QSKE_BIKE3_L5",
+ "QSKE_SIKE_L1",
+ "QSKE_SIKE_L3",
+ "QSKE_SABER_L1",
+ "QSKE_SABER_L3",
+ "QSKE_SABER_L5",
+ "QSKE_LIMA_2P_L3",
+ "QSKE_LIMA_2P_L5",
+ "QSKE_LIMA_SP_L1",
+ "QSKE_LIMA_SP_L2",
+ "QSKE_LIMA_SP_L3",
+ "QSKE_LIMA_SP_L5"
+);
--- /dev/null
+/*
+ * Copyright (C) 2018 Tobias Brunner
+ * Copyright (C) 2018 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup qske_mechanism qske_mechanism
+ * @{ @ingroup crypto
+ */
+
+#ifndef QSKE_MECHANISM_H_
+#define QSKE_MECHANISM_H_
+
+typedef enum qske_mechanism_t qske_mechanism_t;
+typedef struct qske_t qske_t;
+typedef struct qske_params_t qske_params_t;
+
+#include <library.h>
+
+/**
+ * Quantum-Safe Key Encapsulation Mechanism
+ *
+ * KEM Candidates from the NIST Post-Quantum Cryptograpy Round 1 Submissions
+ */
+enum qske_mechanism_t {
+ QSKE_NONE = 0,
+ QSKE_NEWHOPE = 1,
+ QSKE_NEWHOPE_L1 = 2,
+ QSKE_NEWHOPE_L5 = 3,
+ QSKE_FRODO_AES_L1 = 4,
+ QSKE_FRODO_AES_L3 = 5,
+ QSKE_FRODO_SHAKE_L1 = 6,
+ QSKE_FRODO_SHAKE_L3 = 7,
+ QSKE_KYBER_L1 = 8,
+ QSKE_KYBER_L3 = 9,
+ QSKE_KYBER_L5 = 10,
+ QSKE_BIKE1_L1 = 11,
+ QSKE_BIKE1_L3 = 12,
+ QSKE_BIKE1_L5 = 13,
+ QSKE_BIKE2_L1 = 14,
+ QSKE_BIKE2_L3 = 15,
+ QSKE_BIKE2_L5 = 16,
+ QSKE_BIKE3_L1 = 17,
+ QSKE_BIKE3_L3 = 18,
+ QSKE_BIKE3_L5 = 19,
+ QSKE_SIKE_L1 = 20,
+ QSKE_SIKE_L3 = 21,
+ QSKE_SABER_L1 = 22,
+ QSKE_SABER_L3 = 23,
+ QSKE_SABER_L5 = 24,
+ QSKE_LIMA_2P_L3 = 25,
+ QSKE_LIMA_2P_L5 = 26,
+ QSKE_LIMA_SP_L1 = 27,
+ QSKE_LIMA_SP_L2 = 28,
+ QSKE_LIMA_SP_L3 = 29,
+ QSKE_LIMA_SP_L5 = 30
+};
+
+/**
+ * enum name for qske_mechanism_t.
+ */
+extern enum_name_t *qske_mechanism_names;
+
+/**
+ * Implementation of a Quantum-Safe Key Encapsulation Mechanism
+ */
+struct qske_t {
+
+ /**
+ * Get the QSKE mechanism used.
+ *
+ * @return QSKE mechanism
+ */
+ qske_mechanism_t (*get_qske_mechanism) (qske_t *this);
+
+ /**
+ * Get the transport-encpded QSKE public key.
+ *
+ * @param value Transport-encoded QSKE public key (allocated)
+ * @return TRUE if encoding successful
+ */
+ bool (*get_public_key) (qske_t *this, chunk_t *value)
+ __attribute__((warn_unused_result));
+
+ /**
+ * Set the transport-encoded QSKE public key
+ *
+ * @param value Transport-encoded QSKE public key
+ * @return TRUE if decoding successful
+ */
+ bool (*set_public_key) (qske_t *this, chunk_t value)
+ __attribute__((warn_unused_result));
+
+ /**
+ * Get the transport-encoded encrypted shared secret
+ *
+ * @param value Transport-encode encrypted shared secret (allocated)
+ * @return TRUE if shared secret successfully encrypted
+ */
+ bool (*get_ciphertext) (qske_t *this, chunk_t *value)
+ __attribute__((warn_unused_result));
+
+ /**
+ * Set the transport-encoded encrypted shared secret and decrypt it
+ *
+ * @param value Transport-encoded encrypted shared secret
+ * @return TRUE if shared secret successfully decrypted
+ */
+ bool (*set_ciphertext) (qske_t *this, chunk_t value)
+ __attribute__((warn_unused_result));
+
+ /**
+ * Get the shared secret
+ *
+ * @param secret Shared secret (allocated)
+ * @return TRUE if shared secret successfully retrieved
+ */
+ bool (*get_shared_secret) (qske_t *this, chunk_t *secret)
+ __attribute__((warn_unused_result));
+
+ /**
+ * Set the internal RNG to deterministic NIST DRGB test mode
+ * Use for testing purposes only!
+ *
+ * @param enable if TRUE enable NIST DRBG mode, else revert to RNG
+ * @param seed Seed for initializing NIST DRBG
+ * @return TRUE if NIST DRBG test mode available
+ */
+ bool (*set_nist_drbg_mode) (qske_t *this, bool enable, chunk_t seed);
+
+ /**
+ * Destroys a qske_t object.
+ */
+ void (*destroy) (qske_t *this);
+};
+
+#endif /** QSKE_MECHANISM_H_ @}*/
/*
* Copyright (C) 2006-2009 Martin Willi
+ * Copyright (C) 2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
#include <crypto/transform.h>
#include <crypto/hashers/hasher.h>
#include <crypto/rngs/rng.h>
+#include <crypto/qske_mechanism.h>
ENUM_BEGIN(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS,
"ENCRYPTION_ALGORITHM",
"INTEGRITY_ALGORITHM",
"DIFFIE_HELLMAN_GROUP",
"EXTENDED_SEQUENCE_NUMBERS");
-ENUM_NEXT(transform_type_names, HASH_ALGORITHM, EXTENDED_OUTPUT_FUNCTION,
- EXTENDED_SEQUENCE_NUMBERS,
+ENUM_NEXT(transform_type_names, QSKE_MECHANISM,
+ EXTENDED_OUTPUT_FUNCTION, EXTENDED_SEQUENCE_NUMBERS,
+ "QSKE_MECHANISM",
"HASH_ALGORITHM",
"RANDOM_NUMBER_GENERATOR",
"AEAD_ALGORITHM",
return ext_out_function_names;
case COMPRESSION_ALGORITHM:
break;
+ case QSKE_MECHANISM:
+ return qske_mechanism_names;
}
return NULL;
}
/*
* Copyright (C) 2006-2009 Martin Willi
+ * Copyright (C) 2018 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
INTEGRITY_ALGORITHM = 3,
DIFFIE_HELLMAN_GROUP = 4,
EXTENDED_SEQUENCE_NUMBERS = 5,
+ QSKE_MECHANISM = 255,
HASH_ALGORITHM = 256,
RANDOM_NUMBER_GENERATOR = 257,
AEAD_ALGORITHM = 258,
"PRF",
"XOF",
"DH",
+ "QSKE"
"RNG",
"NONCE_GEN",
"PRIVKEY",
case FEATURE_DH:
data = chunk_from_thing(feature->arg.dh_group);
break;
+ case FEATURE_QSKE:
+ data = chunk_from_thing(feature->arg.qske_mechanism);
+ break;
case FEATURE_PRIVKEY:
data = chunk_from_thing(feature->arg.privkey);
break;
return a->arg.xof == b->arg.xof;
case FEATURE_DH:
return a->arg.dh_group == b->arg.dh_group;
+ case FEATURE_QSKE:
+ return a->arg.qske_mechanism == b->arg.qske_mechanism;
case FEATURE_RNG:
return a->arg.rng_quality <= b->arg.rng_quality;
case FEATURE_NONCE_GEN:
case FEATURE_PRF:
case FEATURE_XOF:
case FEATURE_DH:
+ case FEATURE_QSKE:
case FEATURE_NONCE_GEN:
case FEATURE_RESOLVER:
case FEATURE_PRIVKEY:
return str;
}
break;
+ case FEATURE_QSKE:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ qske_mechanism_names, feature->arg.qske_mechanism) > 0)
+ {
+ return str;
+ }
+ break;
case FEATURE_RNG:
if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
rng_quality_names, feature->arg.rng_quality) > 0)
lib->crypto->add_dh(lib->crypto, feature->arg.dh_group,
name, reg->arg.reg.f);
break;
+ case FEATURE_QSKE:
+ lib->crypto->add_qske(lib->crypto, feature->arg.qske_mechanism,
+ name, reg->arg.reg.f);
+ break;
case FEATURE_RNG:
lib->crypto->add_rng(lib->crypto, feature->arg.rng_quality,
name, reg->arg.reg.f);
case FEATURE_DH:
lib->crypto->remove_dh(lib->crypto, reg->arg.reg.f);
break;
+ case FEATURE_QSKE:
+ lib->crypto->remove_qske(lib->crypto, reg->arg.reg.f);
+ break;
case FEATURE_RNG:
lib->crypto->remove_rng(lib->crypto, reg->arg.reg.f);
break;
FEATURE_XOF,
/** diffie_hellman_t */
FEATURE_DH,
+ /** qske_t */
+ FEATURE_QSKE,
/** rng_t */
FEATURE_RNG,
/** nonce_gen_t */
hash_algorithm_t hasher;
/** FEATURE_DH */
diffie_hellman_group_t dh_group;
+ /** FEATURE_QSKE */
+ qske_mechanism_t qske_mechanism;
/** FEATURE_RNG */
rng_quality_t rng_quality;
/** FEATURE_PRIVKEY */
#define _PLUGIN_FEATURE_PRF(kind, alg) __PLUGIN_FEATURE(kind, PRF, .prf = alg)
#define _PLUGIN_FEATURE_XOF(kind, alg) __PLUGIN_FEATURE(kind, XOF, .xof = alg)
#define _PLUGIN_FEATURE_DH(kind, group) __PLUGIN_FEATURE(kind, DH, .dh_group = group)
+#define _PLUGIN_FEATURE_QSKE(kind, mechanism) __PLUGIN_FEATURE(kind, QSKE, .qske_mechanism = mechanism)
#define _PLUGIN_FEATURE_RNG(kind, quality) __PLUGIN_FEATURE(kind, RNG, .rng_quality = quality)
#define _PLUGIN_FEATURE_NONCE_GEN(kind, ...) __PLUGIN_FEATURE(kind, NONCE_GEN, .custom = NULL)
#define _PLUGIN_FEATURE_PRIVKEY(kind, type) __PLUGIN_FEATURE(kind, PRIVKEY, .privkey = type)
#define _PLUGIN_FEATURE_REGISTER_PRF(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
#define _PLUGIN_FEATURE_REGISTER_XOF(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
#define _PLUGIN_FEATURE_REGISTER_DH(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
+#define _PLUGIN_FEATURE_REGISTER_QSKE(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
#define _PLUGIN_FEATURE_REGISTER_RNG(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
#define _PLUGIN_FEATURE_REGISTER_NONCE_GEN(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
#define _PLUGIN_FEATURE_REGISTER_PRIVKEY(type, f, final) __PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final)