diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c index 6c5703a16..cec26579d 100644 --- a/src/libcharon/plugins/stroke/stroke_list.c +++ b/src/libcharon/plugins/stroke/stroke_list.c @@ -844,6 +844,7 @@ static void list_algs(FILE *out) integrity_algorithm_t integrity; hash_algorithm_t hash; pseudo_random_function_t prf; + ext_out_function_t xof; diffie_hellman_group_t group; rng_quality_t quality; const char *plugin_name; @@ -891,6 +892,14 @@ static void list_algs(FILE *out) print_alg(out, &len, pseudo_random_function_names, prf, plugin_name); } enumerator->destroy(enumerator); + fprintf(out, "\n xof: "); + len = 13; + enumerator = lib->crypto->create_xof_enumerator(lib->crypto); + while (enumerator->enumerate(enumerator, &xof, &plugin_name)) + { + print_alg(out, &len, ext_out_function_names, xof, plugin_name); + } + enumerator->destroy(enumerator); fprintf(out, "\n dh-group: "); len = 13; enumerator = lib->crypto->create_dh_enumerator(lib->crypto); diff --git a/src/libcharon/plugins/vici/vici_query.c b/src/libcharon/plugins/vici/vici_query.c index 04cea004e..828b61927 100644 --- a/src/libcharon/plugins/vici/vici_query.c +++ b/src/libcharon/plugins/vici/vici_query.c @@ -1072,6 +1072,7 @@ CALLBACK(get_algorithms, vici_message_t*, integrity_algorithm_t integrity; hash_algorithm_t hash; pseudo_random_function_t prf; + ext_out_function_t xof; diffie_hellman_group_t group; rng_quality_t quality; const char *plugin_name; @@ -1123,6 +1124,15 @@ CALLBACK(get_algorithms, vici_message_t*, enumerator->destroy(enumerator); b->end_section(b); + b->begin_section(b, "xof"); + enumerator = lib->crypto->create_xof_enumerator(lib->crypto); + while (enumerator->enumerate(enumerator, &xof, &plugin_name)) + { + add_algorithm(b, ext_out_function_names, xof, plugin_name); + } + enumerator->destroy(enumerator); + b->end_section(b); + b->begin_section(b, "dh"); enumerator = lib->crypto->create_dh_enumerator(lib->crypto); while (enumerator->enumerate(enumerator, &group, &plugin_name)) diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index 9be93f1f8..965bf7a59 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -15,6 +15,7 @@ crypto/diffie_hellman.c crypto/aead.c crypto/transform.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/mgf1/mgf1.c crypto/mgf1/mgf1_bitspender.c \ +crypto/xofs/xof.h crypto/xofs/xof.c \ credentials/credential_factory.c credentials/builder.c \ credentials/cred_encoding.c credentials/keys/private_key.c \ credentials/keys/public_key.c credentials/keys/shared_key.c \ diff --git a/src/libstrongswan/crypto/crypto_factory.c b/src/libstrongswan/crypto/crypto_factory.c index 35dcf25ac..bab59a06f 100644 --- a/src/libstrongswan/crypto/crypto_factory.c +++ b/src/libstrongswan/crypto/crypto_factory.c @@ -1,7 +1,8 @@ /* * Copyright (C) 2013-2014 Tobias Brunner * Copyright (C) 2008 Martin Willi - * Hochschule fuer Technik Rapperswil + * Copyright (C) 2016 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 @@ -51,6 +52,7 @@ struct entry_t { signer_constructor_t create_signer; hasher_constructor_t create_hasher; prf_constructor_t create_prf; + xof_constructor_t create_xof; rng_constructor_t create_rng; nonce_gen_constructor_t create_nonce_gen; dh_constructor_t create_dh; @@ -95,6 +97,11 @@ struct private_crypto_factory_t { */ linked_list_t *prfs; + /** + * registered xofs, as entry_t + */ + linked_list_t *xofs; + /** * registered rngs, as entry_t */ @@ -303,6 +310,38 @@ METHOD(crypto_factory_t, create_prf, prf_t*, return prf; } +METHOD(crypto_factory_t, create_xof, xof_t*, + private_crypto_factory_t *this, ext_out_function_t algo) +{ + enumerator_t *enumerator; + entry_t *entry; + xof_t *xof = NULL; + + this->lock->read_lock(this->lock); + enumerator = this->xofs->create_enumerator(this->xofs); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->algo == algo) + { + if (this->test_on_create && + !this->tester->test_xof(this->tester, algo, + entry->create_xof, NULL, + default_plugin_name)) + { + continue; + } + xof = entry->create_xof(algo); + if (xof) + { + break; + } + } + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); + return xof; +} + METHOD(crypto_factory_t, create_rng, rng_t*, private_crypto_factory_t *this, rng_quality_t quality) { @@ -633,6 +672,43 @@ METHOD(crypto_factory_t, remove_prf, void, this->lock->unlock(this->lock); } +METHOD(crypto_factory_t, add_xof, bool, + private_crypto_factory_t *this, ext_out_function_t algo, + const char *plugin_name, xof_constructor_t create) +{ + u_int speed = 0; + + if (!this->test_on_add || + this->tester->test_xof(this->tester, algo, create, + this->bench ? &speed : NULL, plugin_name)) + { + add_entry(this, this->xofs, algo, plugin_name, speed, create); + return TRUE; + } + this->test_failures++; + return FALSE; +} + +METHOD(crypto_factory_t, remove_xof, void, + private_crypto_factory_t *this, xof_constructor_t create) +{ + entry_t *entry; + enumerator_t *enumerator; + + this->lock->write_lock(this->lock); + enumerator = this->xofs->create_enumerator(this->xofs); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->create_xof == create) + { + this->xofs->remove_at(this->xofs, enumerator); + free(entry); + } + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); +} + METHOD(crypto_factory_t, add_rng, bool, private_crypto_factory_t *this, rng_quality_t quality, const char *plugin_name, rng_constructor_t create) @@ -845,6 +921,23 @@ METHOD(crypto_factory_t, create_prf_enumerator, enumerator_t*, return create_enumerator(this, this->prfs, prf_filter); } +/** + * Filter function to enumerate algorithm, not entry + */ +static bool xof_filter(void *n, entry_t **entry, ext_out_function_t *algo, + void *i2, const char **plugin_name) +{ + *algo = (*entry)->algo; + *plugin_name = (*entry)->plugin_name; + return TRUE; +} + +METHOD(crypto_factory_t, create_xof_enumerator, enumerator_t*, + private_crypto_factory_t *this) +{ + return create_enumerator(this, this->xofs, xof_filter); +} + /** * Filter function to enumerate group, not entry */ @@ -909,6 +1002,8 @@ METHOD(crypto_factory_t, add_test_vector, void, return this->tester->add_hasher_vector(this->tester, vector); case PSEUDO_RANDOM_FUNCTION: return this->tester->add_prf_vector(this->tester, vector); + case EXTENDED_OUTPUT_FUNCTION: + return this->tester->add_xof_vector(this->tester, vector); case RANDOM_NUMBER_GENERATOR: return this->tester->add_rng_vector(this->tester, vector); case DIFFIE_HELLMAN_GROUP: @@ -961,6 +1056,10 @@ METHOD(enumerator_t, verify_enumerate, bool, *valid = this->tester->test_prf(this->tester, entry->algo, entry->create_prf, NULL, entry->plugin_name); break; + case EXTENDED_OUTPUT_FUNCTION: + *valid = this->tester->test_xof(this->tester, entry->algo, + entry->create_xof, NULL, entry->plugin_name); + break; case RANDOM_NUMBER_GENERATOR: *valid = this->tester->test_rng(this->tester, entry->algo, entry->create_rng, NULL, entry->plugin_name); @@ -1009,6 +1108,9 @@ METHOD(crypto_factory_t, create_verify_enumerator, enumerator_t*, case PSEUDO_RANDOM_FUNCTION: inner = this->prfs->create_enumerator(this->prfs); break; + case EXTENDED_OUTPUT_FUNCTION: + inner = this->xofs->create_enumerator(this->xofs); + break; case RANDOM_NUMBER_GENERATOR: inner = this->rngs->create_enumerator(this->rngs); break; @@ -1040,6 +1142,7 @@ METHOD(crypto_factory_t, destroy, void, this->signers->destroy(this->signers); this->hashers->destroy(this->hashers); this->prfs->destroy(this->prfs); + this->xofs->destroy(this->xofs); this->rngs->destroy(this->rngs); this->nonce_gens->destroy(this->nonce_gens); this->dhs->destroy(this->dhs); @@ -1062,6 +1165,7 @@ crypto_factory_t *crypto_factory_create() .create_signer = _create_signer, .create_hasher = _create_hasher, .create_prf = _create_prf, + .create_xof = _create_xof, .create_rng = _create_rng, .create_nonce_gen = _create_nonce_gen, .create_dh = _create_dh, @@ -1075,6 +1179,8 @@ crypto_factory_t *crypto_factory_create() .remove_hasher = _remove_hasher, .add_prf = _add_prf, .remove_prf = _remove_prf, + .add_xof = _add_xof, + .remove_xof = _remove_xof, .add_rng = _add_rng, .remove_rng = _remove_rng, .add_nonce_gen = _add_nonce_gen, @@ -1086,6 +1192,7 @@ crypto_factory_t *crypto_factory_create() .create_signer_enumerator = _create_signer_enumerator, .create_hasher_enumerator = _create_hasher_enumerator, .create_prf_enumerator = _create_prf_enumerator, + .create_xof_enumerator = _create_xof_enumerator, .create_dh_enumerator = _create_dh_enumerator, .create_rng_enumerator = _create_rng_enumerator, .create_nonce_gen_enumerator = _create_nonce_gen_enumerator, @@ -1098,6 +1205,7 @@ crypto_factory_t *crypto_factory_create() .signers = linked_list_create(), .hashers = linked_list_create(), .prfs = linked_list_create(), + .xofs = linked_list_create(), .rngs = linked_list_create(), .nonce_gens = linked_list_create(), .dhs = linked_list_create(), diff --git a/src/libstrongswan/crypto/crypto_factory.h b/src/libstrongswan/crypto/crypto_factory.h index e03915603..4f61ba1fc 100644 --- a/src/libstrongswan/crypto/crypto_factory.h +++ b/src/libstrongswan/crypto/crypto_factory.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2008 Martin Willi - * Hochschule fuer Technik Rapperswil + * Copyright (C) 2016 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 @@ -31,6 +32,7 @@ typedef struct crypto_factory_t crypto_factory_t; #include #include #include +#include #include #include #include @@ -62,6 +64,11 @@ typedef hasher_t* (*hasher_constructor_t)(hash_algorithm_t algo); */ typedef prf_t* (*prf_constructor_t)(pseudo_random_function_t algo); +/** + * Constructor function for pseudo random functions + */ +typedef xof_t* (*xof_constructor_t)(ext_out_function_t algo); + /** * Constructor function for source of randomness */ @@ -132,6 +139,14 @@ struct crypto_factory_t { */ prf_t* (*create_prf)(crypto_factory_t *this, pseudo_random_function_t algo); + /** + * Create an extended output function instance. + * + * @param algo XOF algorithm to use + * @return xof_t instance, NULL if not supported + */ + xof_t* (*create_xof)(crypto_factory_t *this, ext_out_function_t algo); + /** * Create a source of randomness. * @@ -252,6 +267,24 @@ struct crypto_factory_t { */ void (*remove_prf)(crypto_factory_t *this, prf_constructor_t create); + /** + * Register an xof constructor. + * + * @param algo algorithm 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_xof)(crypto_factory_t *this, ext_out_function_t algo, + const char *plugin_name, xof_constructor_t create); + + /** + * Unregister an xof constructor. + * + * @param create constructor function to unregister + */ + void (*remove_xof)(crypto_factory_t *this, xof_constructor_t create); + /** * Register a source of randomness. * @@ -341,6 +374,13 @@ struct crypto_factory_t { */ enumerator_t* (*create_prf_enumerator)(crypto_factory_t *this); + /** + * Create an enumerator over all registered XOFs. + * + * @return enumerator over ext_out_function_t, plugin + */ + enumerator_t* (*create_xof_enumerator)(crypto_factory_t *this); + /** * Create an enumerator over all registered diffie hellman groups. * diff --git a/src/libstrongswan/crypto/crypto_tester.c b/src/libstrongswan/crypto/crypto_tester.c index 5607d35b9..e86e7ae76 100644 --- a/src/libstrongswan/crypto/crypto_tester.c +++ b/src/libstrongswan/crypto/crypto_tester.c @@ -62,6 +62,11 @@ struct private_crypto_tester_t { */ linked_list_t *prf; + /** + * List of XOF test vectors + */ + linked_list_t *xof; + /** * List of RNG test vectors */ @@ -1034,6 +1039,146 @@ failure: return !failed; } +/** + * Benchmark an XOF + */ +static u_int bench_xof(private_crypto_tester_t *this, + ext_out_function_t alg, xof_constructor_t create) +{ + xof_t *xof; + + xof = create(alg); + if (xof) + { + char seed[xof->get_seed_size(xof)]; + char bytes[xof->get_block_size(xof)]; + struct timespec start; + u_int runs; + + memset(seed, 0x56, xof->get_seed_size(xof)); + if (!xof->set_seed(xof, chunk_create(seed, xof->get_seed_size(xof)))) + { + xof->destroy(xof); + return 0; + } + + runs = 0; + start_timing(&start); + while (end_timing(&start) < this->bench_time) + { + if (xof->get_bytes(xof, xof->get_block_size(xof), bytes)) + { + runs++; + } + } + xof->destroy(xof); + + return runs; + } + return 0; +} + +METHOD(crypto_tester_t, test_xof, bool, + private_crypto_tester_t *this, ext_out_function_t alg, + xof_constructor_t create, u_int *speed, const char *plugin_name) +{ + enumerator_t *enumerator; + xof_test_vector_t *vector; + bool failed = FALSE; + u_int tested = 0; + + enumerator = this->xof->create_enumerator(this->xof); + while (enumerator->enumerate(enumerator, &vector)) + { + xof_t *xof; + chunk_t seed, out = chunk_empty; + + if (vector->alg != alg) + { + continue; + } + + tested++; + failed = TRUE; + xof = create(alg); + if (!xof) + { + DBG1(DBG_LIB, "disabled %N[%s]: creating instance failed", + ext_out_function_names, alg, plugin_name); + break; + } + + seed = chunk_create(vector->seed, vector->len); + if (!xof->set_seed(xof, seed)) + { + goto failure; + } + /* allocated bytes */ + if (!xof->allocate_bytes(xof, vector->out_len, &out)) + { + goto failure; + } + if (out.len != vector->out_len) + { + goto failure; + } + if (!memeq(vector->out, out.ptr, out.len)) + { + goto failure; + } + /* bytes to existing buffer */ + memset(out.ptr, 0, out.len); + if (!xof->set_seed(xof, seed)) + { + goto failure; + } + if (!xof->get_bytes(xof, vector->out_len, out.ptr)) + { + goto failure; + } + if (!memeq(vector->out, out.ptr, vector->out_len)) + { + goto failure; + } + /* bytes to existing buffer, using append mode */ + /* TODO */ + + failed = FALSE; +failure: + xof->destroy(xof); + chunk_free(&out); + if (failed) + { + DBG1(DBG_LIB, "disabled %N[%s]: %s test vector failed", + ext_out_function_names, alg, plugin_name, get_name(vector)); + break; + } + } + enumerator->destroy(enumerator); + if (!tested) + { + DBG1(DBG_LIB, "%s %N[%s]: no test vectors found", + this->required ? "disabled" : "enabled ", + ext_out_function_names, alg, plugin_name); + return !this->required; + } + if (!failed) + { + if (speed) + { + *speed = bench_xof(this, alg, create); + DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors, %d points", + ext_out_function_names, alg, plugin_name, tested, *speed); + } + else + { + DBG1(DBG_LIB, "enabled %N[%s]: passed %u test vectors", + ext_out_function_names, alg, plugin_name, tested); + } + } + return !failed; +} + /** * Benchmark a RNG */ @@ -1338,6 +1483,12 @@ METHOD(crypto_tester_t, add_prf_vector, void, this->prf->insert_last(this->prf, vector); } +METHOD(crypto_tester_t, add_xof_vector, void, + private_crypto_tester_t *this, xof_test_vector_t *vector) +{ + this->xof->insert_last(this->xof, vector); +} + METHOD(crypto_tester_t, add_rng_vector, void, private_crypto_tester_t *this, rng_test_vector_t *vector) { @@ -1358,6 +1509,7 @@ METHOD(crypto_tester_t, destroy, void, this->signer->destroy(this->signer); this->hasher->destroy(this->hasher); this->prf->destroy(this->prf); + this->xof->destroy(this->xof); this->rng->destroy(this->rng); this->dh->destroy(this->dh); free(this); @@ -1377,6 +1529,7 @@ crypto_tester_t *crypto_tester_create() .test_signer = _test_signer, .test_hasher = _test_hasher, .test_prf = _test_prf, + .test_xof = _test_xof, .test_rng = _test_rng, .test_dh = _test_dh, .add_crypter_vector = _add_crypter_vector, @@ -1384,6 +1537,7 @@ crypto_tester_t *crypto_tester_create() .add_signer_vector = _add_signer_vector, .add_hasher_vector = _add_hasher_vector, .add_prf_vector = _add_prf_vector, + .add_xof_vector = _add_xof_vector, .add_rng_vector = _add_rng_vector, .add_dh_vector = _add_dh_vector, .destroy = _destroy, @@ -1393,6 +1547,7 @@ crypto_tester_t *crypto_tester_create() .signer = linked_list_create(), .hasher = linked_list_create(), .prf = linked_list_create(), + .xof = linked_list_create(), .rng = linked_list_create(), .dh = linked_list_create(), diff --git a/src/libstrongswan/crypto/crypto_tester.h b/src/libstrongswan/crypto/crypto_tester.h index 6cc9b0d57..34dfa9489 100644 --- a/src/libstrongswan/crypto/crypto_tester.h +++ b/src/libstrongswan/crypto/crypto_tester.h @@ -30,6 +30,7 @@ typedef struct aead_test_vector_t aead_test_vector_t; typedef struct signer_test_vector_t signer_test_vector_t; typedef struct hasher_test_vector_t hasher_test_vector_t; typedef struct prf_test_vector_t prf_test_vector_t; +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; @@ -114,6 +115,19 @@ struct prf_test_vector_t { u_char *out; }; +struct xof_test_vector_t { + /** xof algorithm this test vector tests */ + ext_out_function_t alg; + /** size of the seed data */ + size_t len; + /** seed data */ + u_char *seed; + /** size of the output */ + size_t out_len; + /** expected output of size*/ + u_char *out; +}; + /** * Test vector for a RNG. * @@ -216,6 +230,17 @@ struct crypto_tester_t { bool (*test_prf)(crypto_tester_t *this, pseudo_random_function_t alg, prf_constructor_t create, u_int *speed, const char *plugin_name); + /** + * Test an XOF algorithm. + * + * @param alg algorithm to test + * @param create constructor function for the XOF + * @param speed speed test result, NULL to omit + * @return TRUE if test passed + */ + bool (*test_xof)(crypto_tester_t *this, ext_out_function_t alg, + xof_constructor_t create, + u_int *speed, const char *plugin_name); /** * Test a RNG implementation. * @@ -274,6 +299,13 @@ struct crypto_tester_t { */ void (*add_prf_vector)(crypto_tester_t *this, prf_test_vector_t *vector); + /** + * Add a test vector to test an XOF. + * + * @param vector pointer to test vector + */ + void (*add_xof_vector)(crypto_tester_t *this, xof_test_vector_t *vector); + /** * Add a test vector to test a RNG. * diff --git a/src/libstrongswan/crypto/transform.c b/src/libstrongswan/crypto/transform.c index 7c6678b61..808cb996e 100644 --- a/src/libstrongswan/crypto/transform.c +++ b/src/libstrongswan/crypto/transform.c @@ -17,13 +17,15 @@ #include #include -ENUM_BEGIN(transform_type_names, UNDEFINED_TRANSFORM_TYPE, COMPRESSION_ALGORITHM, +ENUM_BEGIN(transform_type_names, UNDEFINED_TRANSFORM_TYPE, EXTENDED_OUTPUT_FUNCTION, "UNDEFINED_TRANSFORM_TYPE", "HASH_ALGORITHM", "RANDOM_NUMBER_GENERATOR", "AEAD_ALGORITHM", - "COMPRESSION_ALGORITHM"); -ENUM_NEXT(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS, COMPRESSION_ALGORITHM, + "COMPRESSION_ALGORITHM", + "EXTENDED OUTPUT FUNCTION"); +ENUM_NEXT(transform_type_names, ENCRYPTION_ALGORITHM, EXTENDED_SEQUENCE_NUMBERS, + EXTENDED_OUTPUT_FUNCTION, "ENCRYPTION_ALGORITHM", "PSEUDO_RANDOM_FUNCTION", "INTEGRITY_ALGORITHM", @@ -60,6 +62,8 @@ enum_name_t* transform_get_enum_names(transform_type_t type) return diffie_hellman_group_names; case EXTENDED_SEQUENCE_NUMBERS: return extended_sequence_numbers_names; + case EXTENDED_OUTPUT_FUNCTION: + return ext_out_function_names; case UNDEFINED_TRANSFORM_TYPE: case COMPRESSION_ALGORITHM: break; diff --git a/src/libstrongswan/crypto/transform.h b/src/libstrongswan/crypto/transform.h index 0cb84f0f5..e043e605c 100644 --- a/src/libstrongswan/crypto/transform.h +++ b/src/libstrongswan/crypto/transform.h @@ -34,6 +34,7 @@ enum transform_type_t { RANDOM_NUMBER_GENERATOR = 243, AEAD_ALGORITHM = 244, COMPRESSION_ALGORITHM = 245, + EXTENDED_OUTPUT_FUNCTION = 246, ENCRYPTION_ALGORITHM = 1, PSEUDO_RANDOM_FUNCTION = 2, INTEGRITY_ALGORITHM = 3, diff --git a/src/libstrongswan/crypto/xofs/xof.c b/src/libstrongswan/crypto/xofs/xof.c new file mode 100644 index 000000000..5a78271ad --- /dev/null +++ b/src/libstrongswan/crypto/xofs/xof.c @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2016 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 . + * + * 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 "xof.h" + +ENUM(ext_out_function_names, XOF_UNDEFINED, XOF_MGF1_SHA512, + "XOF_UNDEFINED", + "XOF_SHAKE128", + "XOF_SHAKE256", + "XOF_MGF1_SHA1", + "XOF_MGF1_SHA256", + "XOF_MGF1_SHA512" +); + diff --git a/src/libstrongswan/crypto/xofs/xof.h b/src/libstrongswan/crypto/xofs/xof.h new file mode 100644 index 000000000..11ef086ec --- /dev/null +++ b/src/libstrongswan/crypto/xofs/xof.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2016 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 . + * + * 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 xof xof + * @{ @ingroup crypto + */ + +#ifndef XOF_H_ +#define XOF_H_ + +typedef enum ext_out_function_t ext_out_function_t; +typedef struct xof_t xof_t; + +#include + +/** + * Extendable Output Functions. + */ +enum ext_out_function_t { + XOF_UNDEFINED, + /** FIPS 202 */ + XOF_SHAKE_128, + /** FIPS 202 */ + XOF_SHAKE_256, + /** RFC 2437 PKCS#1 */ + XOF_MGF1_SHA1, + /** RFC 2437 PKCS#1 */ + XOF_MGF1_SHA256, + /** RFC 2437 PKCS#1 */ + XOF_MGF1_SHA512, +}; + +/** + * enum name for ext_out_function_t. + */ +extern enum_name_t *ext_out_function_names; + +/** + * Generic interface for pseudo-random-functions. + */ +struct xof_t { + + /** + * Generates pseudo random bytes and writes them in the buffer. + * + * @param out_len number of output bytes requested + * @param buffer pointer where the generated bytes will be written + * @return TRUE if bytes generated successfully + */ + bool (*get_bytes)(xof_t *this, size_t out_len, + uint8_t *buffer) __attribute__((warn_unused_result)); + + /** + * Generates pseudo random bytes and allocate space for them. + * + * @param out_len number of output bytes requested + * @param chunk chunk which will hold generated bytes + * @return TRUE if bytes allocated and generated successfully + */ + bool (*allocate_bytes)(xof_t *this, size_t out_len, + chunk_t *chunk) __attribute__((warn_unused_result)); + + /** + * Get the output block size + * + * @return block size in bytes + */ + size_t (*get_block_size)(xof_t *this); + + /** + * Get the recommended minimum seed size + * + * @return seed size in bytes + */ + size_t (*get_seed_size)(xof_t *this); + + /** + * Set the key for this xof_t object. + * + * @param sed seed to set + * @return TRUE if XOF initialized with seed successfully + */ + bool (*set_seed)(xof_t *this, + chunk_t seed) __attribute__((warn_unused_result)); + + /** + * Destroys a xof object. + */ + void (*destroy)(xof_t *this); +}; + +#endif /** XOF_H_ @}*/ diff --git a/src/libstrongswan/plugins/plugin_feature.c b/src/libstrongswan/plugins/plugin_feature.c index 4c92c412c..39d86c82a 100644 --- a/src/libstrongswan/plugins/plugin_feature.c +++ b/src/libstrongswan/plugins/plugin_feature.c @@ -30,6 +30,7 @@ ENUM(plugin_feature_names, FEATURE_NONE, FEATURE_CUSTOM, "SIGNER", "HASHER", "PRF", + "XOF", "DH", "RNG", "NONCE_GEN", @@ -87,6 +88,9 @@ uint32_t plugin_feature_hash(plugin_feature_t *feature) case FEATURE_PRF: data = chunk_from_thing(feature->arg.prf); break; + case FEATURE_XOF: + data = chunk_from_thing(feature->arg.xof); + break; case FEATURE_DH: data = chunk_from_thing(feature->arg.dh_group); break; @@ -160,6 +164,8 @@ bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b) return a->arg.hasher == b->arg.hasher; case FEATURE_PRF: return a->arg.prf == b->arg.prf; + case FEATURE_XOF: + return a->arg.xof == b->arg.xof; case FEATURE_DH: return a->arg.dh_group == b->arg.dh_group; case FEATURE_RNG: @@ -218,6 +224,7 @@ bool plugin_feature_equals(plugin_feature_t *a, plugin_feature_t *b) case FEATURE_SIGNER: case FEATURE_HASHER: case FEATURE_PRF: + case FEATURE_XOF: case FEATURE_DH: case FEATURE_NONCE_GEN: case FEATURE_RESOLVER: @@ -305,6 +312,13 @@ char* plugin_feature_get_string(plugin_feature_t *feature) return str; } break; + case FEATURE_XOF: + if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type, + ext_out_function_names, feature->arg.xof) > 0) + { + return str; + } + break; case FEATURE_DH: if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type, diffie_hellman_group_names, feature->arg.dh_group) > 0) @@ -465,6 +479,10 @@ bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature, lib->crypto->add_prf(lib->crypto, feature->arg.prf, name, reg->arg.reg.f); break; + case FEATURE_XOF: + lib->crypto->add_xof(lib->crypto, feature->arg.xof, + name, reg->arg.reg.f); + break; case FEATURE_DH: lib->crypto->add_dh(lib->crypto, feature->arg.dh_group, name, reg->arg.reg.f); @@ -552,6 +570,9 @@ bool plugin_feature_unload(plugin_t *plugin, plugin_feature_t *feature, case FEATURE_PRF: lib->crypto->remove_prf(lib->crypto, reg->arg.reg.f); break; + case FEATURE_XOF: + lib->crypto->remove_xof(lib->crypto, reg->arg.reg.f); + break; case FEATURE_DH: lib->crypto->remove_dh(lib->crypto, reg->arg.reg.f); break; diff --git a/src/libstrongswan/plugins/plugin_feature.h b/src/libstrongswan/plugins/plugin_feature.h index ee7808a94..8cc6277eb 100644 --- a/src/libstrongswan/plugins/plugin_feature.h +++ b/src/libstrongswan/plugins/plugin_feature.h @@ -110,6 +110,8 @@ struct plugin_feature_t { FEATURE_HASHER, /** prf_t */ FEATURE_PRF, + /** xof_t */ + FEATURE_XOF, /** diffie_hellman_t */ FEATURE_DH, /** rng_t */ @@ -171,6 +173,8 @@ struct plugin_feature_t { integrity_algorithm_t signer; /** FEATURE_PRF */ pseudo_random_function_t prf; + /** FEATURE_XOFF */ + ext_out_function_t xof; /** FEATURE_HASHER */ hash_algorithm_t hasher; /** FEATURE_DH */ @@ -278,6 +282,7 @@ struct plugin_feature_t { #define _PLUGIN_FEATURE_SIGNER(kind, alg) __PLUGIN_FEATURE(kind, SIGNER, .signer = alg) #define _PLUGIN_FEATURE_HASHER(kind, alg) __PLUGIN_FEATURE(kind, HASHER, .hasher = alg) #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_RNG(kind, quality) __PLUGIN_FEATURE(kind, RNG, .rng_quality = quality) #define _PLUGIN_FEATURE_NONCE_GEN(kind, ...) __PLUGIN_FEATURE(kind, NONCE_GEN, .custom = NULL) @@ -310,6 +315,7 @@ struct plugin_feature_t { #define _PLUGIN_FEATURE_REGISTER_SIGNER(type, f) __PLUGIN_FEATURE_REGISTER(type, f) #define _PLUGIN_FEATURE_REGISTER_HASHER(type, f) __PLUGIN_FEATURE_REGISTER(type, f) #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_RNG(type, f) __PLUGIN_FEATURE_REGISTER(type, f) #define _PLUGIN_FEATURE_REGISTER_NONCE_GEN(type, f) __PLUGIN_FEATURE_REGISTER(type, f) diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors_plugin.c b/src/libstrongswan/plugins/test_vectors/test_vectors_plugin.c index 0505e2c40..c4d71848d 100644 --- a/src/libstrongswan/plugins/test_vectors/test_vectors_plugin.c +++ b/src/libstrongswan/plugins/test_vectors/test_vectors_plugin.c @@ -24,6 +24,7 @@ #define TEST_VECTOR_SIGNER(x) extern signer_test_vector_t x; #define TEST_VECTOR_HASHER(x) extern hasher_test_vector_t x; #define TEST_VECTOR_PRF(x) extern prf_test_vector_t x; +#define TEST_VECTOR_XOF(x) extern xof_test_vector_t x; #define TEST_VECTOR_RNG(x) extern rng_test_vector_t x; #define TEST_VECTOR_DH(x) extern dh_test_vector_t x; @@ -34,6 +35,7 @@ #undef TEST_VECTOR_SIGNER #undef TEST_VECTOR_HASHER #undef TEST_VECTOR_PRF +#undef TEST_VECTOR_XOF #undef TEST_VECTOR_RNG #undef TEST_VECTOR_DH @@ -42,6 +44,7 @@ #define TEST_VECTOR_SIGNER(x) #define TEST_VECTOR_HASHER(x) #define TEST_VECTOR_PRF(x) +#define TEST_VECTOR_XOF(x) #define TEST_VECTOR_RNG(x) #define TEST_VECTOR_DH(x) @@ -86,6 +89,14 @@ static prf_test_vector_t *prf[] = { #undef TEST_VECTOR_PRF #define TEST_VECTOR_PRF(x) +#undef TEST_VECTOR_XOF +#define TEST_VECTOR_XOF(x) &x, +static xof_test_vector_t *xof[] = { +#include "test_vectors.h" +}; +#undef TEST_VECTOR_XOF +#define TEST_VECTOR_XOF(x) + #undef TEST_VECTOR_RNG #define TEST_VECTOR_RNG(x) &x, static rng_test_vector_t *rng[] = { @@ -181,6 +192,11 @@ plugin_t *test_vectors_plugin_create() lib->crypto->add_test_vector(lib->crypto, PSEUDO_RANDOM_FUNCTION, prf[i]); } + for (i = 0; i < countof(xof); i++) + { + lib->crypto->add_test_vector(lib->crypto, + EXTENDED_OUTPUT_FUNCTION, xof[i]); + } for (i = 0; i < countof(rng); i++) { lib->crypto->add_test_vector(lib->crypto,