diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2016-09-20 22:01:07 +0200 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2016-09-21 06:40:52 +0200 |
commit | 188b190a70c9e730bfa9f6edb836252832e2880b (patch) | |
tree | 502d74eeff97e773cdfb8f18782018dfa3763eb2 /src/libstrongswan | |
parent | e9e643b240ac6a1c3c8ffd8c7045625b28b4df19 (diff) | |
download | strongswan-188b190a70c9.tar.bz2 strongswan-188b190a70c9.tar.xz |
mgf1: Refactored MGF1 as an XOF
Diffstat (limited to 'src/libstrongswan')
30 files changed, 928 insertions, 615 deletions
diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index c9bcaa737..52ae7c675 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -14,8 +14,7 @@ crypto/signers/mac_signer.c crypto/crypto_factory.c crypto/crypto_tester.c \ 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.c \ +crypto/xofs/xof.c crypto/xofs/xof_bitspender.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 \ @@ -76,8 +75,7 @@ crypto/prf_plus.h crypto/signers/signer.h crypto/signers/mac_signer.h \ crypto/crypto_factory.h crypto/crypto_tester.h crypto/diffie_hellman.h \ crypto/aead.h crypto/transform.h crypto/pkcs5.h crypto/iv/iv_gen.h \ crypto/iv/iv_gen_rand.h crypto/iv/iv_gen_seq.h crypto/iv/iv_gen_null.h \ -crypto/mgf1/mgf1.h crypto/mgf1/mgf1_bitspender.h \ -crypto/xofs/xof.h \ +crypto/xofs/xof.h crypto/xofs/xof_bitspender.h crypto/xofs/mgf1.h \ credentials/credential_factory.h credentials/builder.h \ credentials/cred_encoding.h credentials/keys/private_key.h \ credentials/keys/public_key.h credentials/keys/shared_key.h \ @@ -588,6 +586,13 @@ if MONOLITHIC endif endif +if USE_MGF1 + SUBDIRS += plugins/mgf1 +if MONOLITHIC + libstrongswan_la_LIBADD += plugins/mgf1/libstrongswan-mgf1.la +endif +endif + if USE_NTRU SUBDIRS += plugins/ntru if MONOLITHIC diff --git a/src/libstrongswan/crypto/mgf1/mgf1.c b/src/libstrongswan/crypto/mgf1/mgf1.c deleted file mode 100644 index 5116dfefa..000000000 --- a/src/libstrongswan/crypto/mgf1/mgf1.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2013-2014 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 "mgf1.h" - -#include "crypto/hashers/hasher.h" -#include "utils/debug.h" -#include "utils/test.h" - -typedef struct private_mgf1_t private_mgf1_t; - -/** - * Private data of an mgf1_t object. - */ -struct private_mgf1_t { - - /** - * Public mgf1_t interface. - */ - mgf1_t public; - - /** - * Hasher the MGF1 Mask Generation Function is based on - */ - hasher_t *hasher; - - /** - * Counter - */ - uint32_t counter; - - /** - * Set if counter has reached 2^32 - */ - bool overflow; - - /** - * Current state to be hashed - */ - chunk_t state; - - /** - * Position of the 4 octet counter string - */ - u_char *ctr_str; - -}; - -METHOD(mgf1_t, get_hash_size, size_t, - private_mgf1_t *this) -{ - return this->hasher->get_hash_size(this->hasher); -} - -METHOD(mgf1_t, get_mask, bool, - private_mgf1_t *this, size_t mask_len, u_char *mask) -{ - u_char buf[HASH_SIZE_SHA512]; - size_t hash_len; - - hash_len = this->hasher->get_hash_size(this->hasher); - - while (mask_len > 0) - { - /* detect overflow, set counter string and increment counter */ - if (this->overflow) - { - return FALSE; - } - htoun32(this->ctr_str, this->counter++); - if (this->counter == 0) - { - this->overflow = TRUE; - } - - /* get the next or final mask block from the hash function */ - if (!this->hasher->get_hash(this->hasher, this->state, - (mask_len < hash_len) ? buf : mask)) - { - return FALSE; - } - if (mask_len < hash_len) - { - memcpy(mask, buf, mask_len); - return TRUE; - } - mask_len -= hash_len; - mask += hash_len; - } - return TRUE; -} - -METHOD(mgf1_t, allocate_mask, bool, - private_mgf1_t *this, size_t mask_len, chunk_t *mask) -{ - if (mask_len == 0) - { - *mask = chunk_empty; - return TRUE; - } - *mask = chunk_alloc(mask_len); - - return get_mask(this, mask_len, mask->ptr); -} - -METHOD(mgf1_t, destroy, void, - private_mgf1_t *this) -{ - this->hasher->destroy(this->hasher); - chunk_clear(&this->state); - free(this); -} - -/* - * Described in header. - */ -mgf1_t *mgf1_create(hash_algorithm_t alg, chunk_t seed, - bool hash_seed) -{ - private_mgf1_t *this; - hasher_t *hasher; - size_t state_len; - - if (seed.len == 0) - { - DBG1(DBG_LIB, "empty seed for MGF1"); - return NULL; - } - - hasher = lib->crypto->create_hasher(lib->crypto, alg); - if (!hasher) - { - DBG1(DBG_LIB, "failed to create %N hasher for MGF1", - hash_algorithm_names, alg); - return NULL; - } - state_len = (hash_seed ? hasher->get_hash_size(hasher) : seed.len) + 4; - - INIT(this, - .public = { - .get_hash_size = _get_hash_size, - .allocate_mask = _allocate_mask, - .get_mask = _get_mask, - .destroy = _destroy, - }, - .hasher = hasher, - .state = chunk_alloc(state_len), - ); - - /* determine position of the 4 octet counter string */ - this->ctr_str = this->state.ptr + state_len - 4; - - if (hash_seed) - { - if (!hasher->get_hash(hasher, seed, this->state.ptr)) - { - DBG1(DBG_LIB, "failed to hash seed for MGF1"); - destroy(this); - return NULL; - } - } - else - { - memcpy(this->state.ptr, seed.ptr, seed.len); - } - - return &this->public; -} diff --git a/src/libstrongswan/crypto/mgf1/mgf1.h b/src/libstrongswan/crypto/mgf1/mgf1.h deleted file mode 100644 index 592d31596..000000000 --- a/src/libstrongswan/crypto/mgf1/mgf1.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2013-2014 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 mgf1 mgf1 - * @{ @ingroup crypto - */ - -#ifndef MGF1_H_ -#define MGF1_H_ - -typedef struct mgf1_t mgf1_t; - -#include <library.h> - -/** - * Implements the PKCS#1 MGF1 Mask Generation Function based on a hash function - * defined in section 10.2.1 of RFC 2437 - */ -struct mgf1_t { - - /** - * Get the hash size of the underlying hash function - * - * @return hash size in bytes - */ - size_t (*get_hash_size)(mgf1_t *this); - - /** - * Generate a mask pattern and copy it to an output buffer - * If the maximum number of requests has been reached, reseeding occurs - * - * @param mask_len number of mask bytes to generate - * @param mask output buffer of minimum size mask_len - * @return TRUE if successful - */ - bool (*get_mask)(mgf1_t *this, size_t mask_len, u_char *mask); - - /** - * Generate a mask pattern and return it in an allocated chunk - * - * @param mask_len number of mask bytes to generate - * @param mask chunk containing generated mask - * @return TRUE if successful - */ - bool (*allocate_mask)(mgf1_t *this, size_t mask_len, chunk_t *mask); - - /** - * Destroy the MGF1 object - */ - void (*destroy)(mgf1_t *this); -}; - -/** - * Create an MGF1 object - * - * @param alg hash algorithm to be used by MGF1 - * @param seed seed used by MGF1 to generate mask from - * @param hash_seed hash seed before using it as a seed for MGF1 - */ -mgf1_t *mgf1_create(hash_algorithm_t alg, chunk_t seed, - bool hash_seed); - -#endif /** MGF1_H_ @}*/ - diff --git a/src/libstrongswan/crypto/mgf1/mgf1_bitspender.c b/src/libstrongswan/crypto/mgf1/mgf1_bitspender.c deleted file mode 100644 index ef0a2bd01..000000000 --- a/src/libstrongswan/crypto/mgf1/mgf1_bitspender.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2014 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 "mgf1_bitspender.h" - -#include <crypto/mgf1/mgf1.h> - -typedef struct private_mgf1_bitspender_t private_mgf1_bitspender_t; - -/** - * Private data structure for mgf1_bitspender_t object - */ -struct private_mgf1_bitspender_t { - /** - * Public interface. - */ - mgf1_bitspender_t public; - - /** - * MGF1 bit mask generator - */ - mgf1_t *mgf1; - - /** - * Octet storage (accommodates up to 64 octets) - */ - uint8_t octets[HASH_SIZE_SHA512]; - - /** - * Length of the returned hash value in octets - */ - int hash_len; - - /** - * Number of generated octets - */ - int octets_count; - - /** - * Number of available octets - */ - int octets_left; - - /** - * Bit storage (accommodates up to 32 bits) - */ - uint32_t bits; - - /** - * Number of available bits - */ - int bits_left; - - /** - * Byte storage (accommodates up to 4 bytes) - */ - uint8_t bytes[4]; - - /** - * Number of available bytes - */ - int bytes_left; - -}; - -METHOD(mgf1_bitspender_t, get_bits, bool, - private_mgf1_bitspender_t *this, int bits_needed, uint32_t *bits) -{ - int bits_now; - - *bits = 0x00000000; - - if (bits_needed == 0) - { - /* trivial */ - return TRUE; - } - if (bits_needed > 32) - { - /* too many bits requested */ - return FALSE; - } - - while (bits_needed) - { - if (this->bits_left == 0) - { - if (this->octets_left == 0) - { - /* get another block from MGF1 */ - if (!this->mgf1->get_mask(this->mgf1, this->hash_len, - this->octets)) - { - /* no block available */ - return FALSE; - } - this->octets_left = this->hash_len; - this->octets_count += this->hash_len; - } - this->bits = untoh32(this->octets + this->hash_len - - this->octets_left); - this->bits_left = 32; - this->octets_left -= 4; - } - if (bits_needed > this->bits_left) - { - bits_now = this->bits_left; - this->bits_left = 0; - bits_needed -= bits_now; - } - else - { - bits_now = bits_needed; - this->bits_left -= bits_needed; - bits_needed = 0; - } - if (bits_now == 32) - { - *bits = this->bits; - } - else - { - *bits <<= bits_now; - *bits |= this->bits >> this->bits_left; - if (this->bits_left) - { - this->bits &= 0xffffffff >> (32 - this->bits_left); - } - } - } - return TRUE; -} - -METHOD(mgf1_bitspender_t, get_byte, bool, - private_mgf1_bitspender_t *this, uint8_t *byte) -{ - if (this->bytes_left == 0) - { - if (this->octets_left == 0) - { - /* get another block from MGF1 */ - if (!this->mgf1->get_mask(this->mgf1, this->hash_len, this->octets)) - { - /* no block available */ - return FALSE; - } - this->octets_left = this->hash_len; - this->octets_count += this->hash_len; - } - memcpy(this->bytes, this->octets + this->hash_len - this->octets_left, 4); - this->bytes_left = 4; - this->octets_left -= 4; - } - *byte = this->bytes[4 - this->bytes_left--]; - - return TRUE; -} - -METHOD(mgf1_bitspender_t, destroy, void, - private_mgf1_bitspender_t *this) -{ - DBG2(DBG_LIB, "mgf1 generated %u octets", this->octets_count); - memwipe(this->octets, sizeof(this->octets)); - this->mgf1->destroy(this->mgf1); - free(this); -} - -/** - * See header. - */ -mgf1_bitspender_t *mgf1_bitspender_create(hash_algorithm_t alg, chunk_t seed, - bool hash_seed) -{ - private_mgf1_bitspender_t *this; - mgf1_t *mgf1; - - mgf1 = mgf1_create(alg, seed, hash_seed); - if (!mgf1) - { - return NULL; - } - DBG2(DBG_LIB, "mgf1 based on %N is seeded with %u octets", - hash_algorithm_short_names, alg, seed.len); - - INIT(this, - .public = { - .get_bits = _get_bits, - .get_byte = _get_byte, - .destroy = _destroy, - }, - .mgf1 = mgf1, - .hash_len = mgf1->get_hash_size(mgf1), - ); - - return &this->public; -} diff --git a/src/libstrongswan/crypto/xofs/mgf1.h b/src/libstrongswan/crypto/xofs/mgf1.h new file mode 100644 index 000000000..5ad3a518a --- /dev/null +++ b/src/libstrongswan/crypto/xofs/mgf1.h @@ -0,0 +1,47 @@ +/* + * 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 <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 mgf1 mgf1 + * @{ @ingroup crypto + */ + +#ifndef MGF1_H_ +#define MGF1_H_ + +typedef struct mgf1_t mgf1_t; + +#include "xof.h" + +/** + * Implements the PKCS#1 MGF1 Mask Generation Function based on a hash function + * defined in section 10.2.1 of RFC 2437 + */ +struct mgf1_t { + + /** + * Generic xof_t interface for this Extended Output Function (XOF). + */ + xof_t xof_interface; + + /** + * Hash the seed before using it as a seed for MGF1 + * + * @param yes TRUE if seed has to be hashed first + */ + void (*set_hash_seed)(mgf1_t *this, bool yes); +}; + +#endif /** MGF1_H_ @}*/ diff --git a/src/libstrongswan/crypto/xofs/xof.c b/src/libstrongswan/crypto/xofs/xof.c index 3c5b5d6ed..1e9c2834b 100644 --- a/src/libstrongswan/crypto/xofs/xof.c +++ b/src/libstrongswan/crypto/xofs/xof.c @@ -17,11 +17,11 @@ ENUM(ext_out_function_names, XOF_UNDEFINED, XOF_CHACHA20, "XOF_UNDEFINED", - "XOF_SHAKE128", - "XOF_SHAKE256", "XOF_MGF1_SHA1", "XOF_MGF1_SHA256", "XOF_MGF1_SHA512", + "XOF_SHAKE128", + "XOF_SHAKE256", "XOF_CHACHA20" ); diff --git a/src/libstrongswan/crypto/xofs/xof.h b/src/libstrongswan/crypto/xofs/xof.h index e8acda31a..8c9ae0131 100644 --- a/src/libstrongswan/crypto/xofs/xof.h +++ b/src/libstrongswan/crypto/xofs/xof.h @@ -31,16 +31,16 @@ typedef struct xof_t xof_t; */ 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, + /** FIPS 202 */ + XOF_SHAKE_128, + /** FIPS 202 */ + XOF_SHAKE_256, /** RFC 7539 ChaCha20 */ XOF_CHACHA20, }; @@ -51,11 +51,18 @@ enum ext_out_function_t { extern enum_name_t *ext_out_function_names; /** - * Generic interface for pseudo-random-functions. + * Generic interface for Extended Output Function (XOF) */ struct xof_t { /** + * Return the type of the Extended Output Function + * + * @return XOF type + */ + ext_out_function_t (*get_type)(xof_t *this); + + /** * Generates pseudo random bytes and writes them in the buffer. * * @param out_len number of output bytes requested diff --git a/src/libstrongswan/crypto/xofs/xof_bitspender.c b/src/libstrongswan/crypto/xofs/xof_bitspender.c new file mode 100644 index 000000000..f18b806a3 --- /dev/null +++ b/src/libstrongswan/crypto/xofs/xof_bitspender.c @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2014-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 <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 "xof_bitspender.h" +#include "mgf1.h" + +typedef struct private_xof_bitspender_t private_xof_bitspender_t; + +/** + * Private data structure for xof_bitspender_t object + */ +struct private_xof_bitspender_t { + /** + * Public interface. + */ + xof_bitspender_t public; + + /** + * Extended Output Function (XOF) + */ + xof_t *xof; + + /** + * Length of the returned hash value in octets + */ + int hash_len; + + /** + * Bit storage (accommodates up to 32 bits) + */ + uint32_t bits; + + /** + * Number of available bits + */ + int bits_left; + + /** + * Byte storage (accommodates up to 4 bytes) + */ + uint8_t bytes[4]; + + /** + * Number of available bytes + */ + int bytes_left; + + /** + * Number of octets spent + */ + int octet_count; + +}; + +static bool get_next_block(private_xof_bitspender_t *this, uint8_t *buffer) +{ + if (!this->xof->get_bytes(this->xof, 4, buffer)) + { + /* no block available */ + return FALSE; + } + this->octet_count += 4; + + return TRUE; +} + +METHOD(xof_bitspender_t, get_bits, bool, + private_xof_bitspender_t *this, int bits_needed, uint32_t *bits) +{ + int bits_now; + + *bits = 0x00000000; + + if (bits_needed == 0) + { + /* trivial */ + return TRUE; + } + if (bits_needed > 32) + { + /* too many bits requested */ + return FALSE; + } + + while (bits_needed) + { + if (this->bits_left == 0) + { + uint8_t buf[4]; + + if (!get_next_block(this, buf)) + { + return FALSE; + } + this->bits = untoh32(buf); + this->bits_left = 32; + } + if (bits_needed > this->bits_left) + { + bits_now = this->bits_left; + this->bits_left = 0; + bits_needed -= bits_now; + } + else + { + bits_now = bits_needed; + this->bits_left -= bits_needed; + bits_needed = 0; + } + if (bits_now == 32) + { + *bits = this->bits; + } + else + { + *bits <<= bits_now; + *bits |= this->bits >> this->bits_left; + if (this->bits_left) + { + this->bits &= 0xffffffff >> (32 - this->bits_left); + } + } + } + + return TRUE; +} + +METHOD(xof_bitspender_t, get_byte, bool, + private_xof_bitspender_t *this, uint8_t *byte) +{ + if (this->bytes_left == 0) + { + if (!get_next_block(this, this->bytes)) + { + return FALSE; + } + this->bytes_left = 4; + } + *byte = this->bytes[4 - this->bytes_left--]; + + return TRUE; +} + +METHOD(xof_bitspender_t, destroy, void, + private_xof_bitspender_t *this) +{ + DBG2(DBG_LIB, "%N generated %u octets", ext_out_function_names, + this->xof->get_type(this->xof), this->octet_count); + memwipe(this->bytes, 4); + this->xof->destroy(this->xof); + free(this); +} + +/** + * See header. + */ +xof_bitspender_t *xof_bitspender_create(ext_out_function_t alg, chunk_t seed, + bool hash_seed) +{ + private_xof_bitspender_t *this; + xof_t *xof; + + xof = lib->crypto->create_xof(lib->crypto, alg); + if (!xof) + { + return NULL; + } + + switch (alg) + { + case XOF_MGF1_SHA1: + case XOF_MGF1_SHA256: + case XOF_MGF1_SHA512: + { + mgf1_t *mgf1 = (mgf1_t*)xof; + + mgf1->set_hash_seed(mgf1, hash_seed); + break; + } + default: + break; + } + if (!xof->set_seed(xof, seed)) + { + xof->destroy(xof); + return NULL; + } + DBG2(DBG_LIB, "%N is seeded with %u octets", ext_out_function_names, + alg, seed.len); + + INIT(this, + .public = { + .get_bits = _get_bits, + .get_byte = _get_byte, + .destroy = _destroy, + }, + .xof = xof, + ); + + return &this->public; +} diff --git a/src/libstrongswan/crypto/mgf1/mgf1_bitspender.h b/src/libstrongswan/crypto/xofs/xof_bitspender.h index f7df8e834..f42207903 100644 --- a/src/libstrongswan/crypto/mgf1/mgf1_bitspender.h +++ b/src/libstrongswan/crypto/xofs/xof_bitspender.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Andreas Steffen + * Copyright (C) 2014-2016 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -14,22 +14,24 @@ */ /** - * @defgroup mgf1_bitspender mgf1_bitspender + * @defgroup xof_bitspender xof_bitspender * @{ @ingroup mgf1 */ -#ifndef MGF1_BITSPENDER_H_ -#define MGF1_BITSPENDER_H_ +#ifndef XOF_BITSPENDER_H_ +#define XOF_BITSPENDER_H_ + +#include "xof.h" #include <library.h> -#include <crypto/hashers/hasher.h> -typedef struct mgf1_bitspender_t mgf1_bitspender_t; +typedef struct xof_bitspender_t xof_bitspender_t; /** - * Generates a given number of pseudo-random bits at a time using MGF1 + * Generates a given number of pseudo-random bits at a time using an + * Extended Output Function (XOF) */ -struct mgf1_bitspender_t { +struct xof_bitspender_t { /** * Get pseudo-random bits @@ -38,7 +40,7 @@ struct mgf1_bitspender_t { * @param bits Pseudo-random bits * @result FALSE if internal MGF1 error occurred */ - bool (*get_bits)(mgf1_bitspender_t *this, int bits_needed, uint32_t *bits); + bool (*get_bits)(xof_bitspender_t *this, int bits_needed, uint32_t *bits); /** * Get a pseudo-random byte @@ -46,22 +48,22 @@ struct mgf1_bitspender_t { * @param byte Pseudo-random byte * @result FALSE if internal MGF1 error occurred */ - bool (*get_byte)(mgf1_bitspender_t *this, uint8_t *byte); + bool (*get_byte)(xof_bitspender_t *this, uint8_t *byte); /** - * Destroy mgf1_bitspender_t object + * Destroy xof_bitspender_t object */ - void (*destroy)(mgf1_bitspender_t *this); + void (*destroy)(xof_bitspender_t *this); }; /** - * Create a mgf1_bitspender_t object + * Create a xof_bitspender_t object * - * @param alg Hash algorithm to be used with MGF1 - * @param seed Seed used to initialize MGF1 + * @param alg XOF to be used + * @param seed Seed used to initialize XOF * @param hash_seed Hash seed before using it as a seed for MFG1 */ -mgf1_bitspender_t *mgf1_bitspender_create(hash_algorithm_t alg, chunk_t seed, - bool hash_seed); +xof_bitspender_t *xof_bitspender_create(ext_out_function_t alg, chunk_t seed, + bool hash_seed); -#endif /** MGF1_BITSPENDER_H_ @}*/ +#endif /** XOF_BITSPENDER_H_ @}*/ diff --git a/src/libstrongswan/plugins/bliss/bliss_private_key.c b/src/libstrongswan/plugins/bliss/bliss_private_key.c index 5ec493792..0479f0f8d 100644 --- a/src/libstrongswan/plugins/bliss/bliss_private_key.c +++ b/src/libstrongswan/plugins/bliss/bliss_private_key.c @@ -23,7 +23,7 @@ #include "ntt_fft.h" #include "ntt_fft_reduce.h" -#include <crypto/mgf1/mgf1_bitspender.h> +#include <crypto/xofs/xof_bitspender.h> #include <asn1/asn1.h> #include <asn1/asn1_parser.h> #include <asn1/oid.h> @@ -174,7 +174,8 @@ static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg, bliss_sampler_t *sampler = NULL; rng_t *rng; hasher_t *hasher; - hash_algorithm_t mgf1_alg, oracle_alg; + hash_algorithm_t mgf1_alg; + ext_out_function_t oracle_alg; size_t mgf1_seed_len; uint8_t mgf1_seed_buf[HASH_SIZE_SHA512], data_hash_buf[HASH_SIZE_SHA512]; chunk_t mgf1_seed, data_hash; @@ -226,7 +227,7 @@ static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg, } /* MGF1 hash algorithm to be used for random oracle */ - oracle_alg = HASH_SHA512; + oracle_alg = XOF_MGF1_SHA512; /* Initialize a couple of needed variables */ n = this->set->n; @@ -834,14 +835,14 @@ static uint32_t invert(private_bliss_private_key_t *this, uint32_t x) * Create a vector with sparse and small coefficients from seed */ static int8_t* create_vector_from_seed(private_bliss_private_key_t *this, - hash_algorithm_t alg, chunk_t seed) + ext_out_function_t alg, chunk_t seed) { - mgf1_bitspender_t *bitspender; + xof_bitspender_t *bitspender; uint32_t index, sign; int8_t *vector; int non_zero; - bitspender = mgf1_bitspender_create(alg, seed, FALSE); + bitspender = xof_bitspender_create(alg, seed, FALSE); if (!bitspender) { return NULL; @@ -910,7 +911,7 @@ static bool create_secret(private_bliss_private_key_t *this, rng_t *rng, int i, n; chunk_t seed; size_t seed_len; - hash_algorithm_t alg; + ext_out_function_t alg; n = this->set->n; *s1 = NULL; @@ -919,12 +920,12 @@ static bool create_secret(private_bliss_private_key_t *this, rng_t *rng, /* Set MGF1 hash algorithm and seed length based on security strength */ if (this->set->strength > 160) { - alg = HASH_SHA256; + alg = XOF_MGF1_SHA256; seed_len = HASH_SIZE_SHA256; } else { - alg = HASH_SHA1; + alg = XOF_MGF1_SHA1; seed_len = HASH_SIZE_SHA1; } seed = chunk_create(seed_buf, seed_len); diff --git a/src/libstrongswan/plugins/bliss/bliss_public_key.c b/src/libstrongswan/plugins/bliss/bliss_public_key.c index 0ef87e288..f7ddbbfd2 100644 --- a/src/libstrongswan/plugins/bliss/bliss_public_key.c +++ b/src/libstrongswan/plugins/bliss/bliss_public_key.c @@ -76,7 +76,7 @@ static bool verify_bliss(private_bliss_public_key_t *this, hash_algorithm_t alg, uint8_t data_hash_buf[HASH_SIZE_SHA512]; chunk_t data_hash; hasher_t *hasher; - hash_algorithm_t oracle_alg; + ext_out_function_t oracle_alg; ntt_fft_t *fft; bliss_signature_t *sig; bool success = FALSE; @@ -110,7 +110,7 @@ static bool verify_bliss(private_bliss_public_key_t *this, hash_algorithm_t alg, } /* MGF1 hash algorithm to be used for random oracle */ - oracle_alg = HASH_SHA512; + oracle_alg = XOF_MGF1_SHA512; /* Initialize a couple of needed variables */ n = this->set->n; diff --git a/src/libstrongswan/plugins/bliss/bliss_sampler.c b/src/libstrongswan/plugins/bliss/bliss_sampler.c index 717c15ff7..fb29d6622 100644 --- a/src/libstrongswan/plugins/bliss/bliss_sampler.c +++ b/src/libstrongswan/plugins/bliss/bliss_sampler.c @@ -17,7 +17,7 @@ typedef struct private_bliss_sampler_t private_bliss_sampler_t; -#include <crypto/mgf1/mgf1_bitspender.h> +#include <crypto/xofs/xof_bitspender.h> /** * Private data of a bliss_sampler_t object. @@ -37,7 +37,7 @@ struct private_bliss_sampler_t { /** * Bitspender used for random rejection sampling */ - mgf1_bitspender_t *bitspender; + xof_bitspender_t *bitspender; }; @@ -222,13 +222,13 @@ METHOD(bliss_sampler_t, destroy, void, /** * See header. */ -bliss_sampler_t *bliss_sampler_create(hash_algorithm_t alg, chunk_t seed, +bliss_sampler_t *bliss_sampler_create(ext_out_function_t alg, chunk_t seed, const bliss_param_set_t *set) { private_bliss_sampler_t *this; - mgf1_bitspender_t *bitspender; + xof_bitspender_t *bitspender; - bitspender = mgf1_bitspender_create(alg, seed, FALSE); + bitspender = xof_bitspender_create(alg, seed, FALSE); if (!bitspender) { return NULL; diff --git a/src/libstrongswan/plugins/bliss/bliss_sampler.h b/src/libstrongswan/plugins/bliss/bliss_sampler.h index 22562b228..3e6d3d003 100644 --- a/src/libstrongswan/plugins/bliss/bliss_sampler.h +++ b/src/libstrongswan/plugins/bliss/bliss_sampler.h @@ -84,11 +84,11 @@ struct bliss_sampler_t { /** * Create a bliss_sampler_t object. * - * @param alg Hash algorithm to be used for the internal bitspender + * @param alg XOF to be used for the internal bitspender * @param seed Seed used to initialize the internal bitspender * @param set BLISS parameter set to be used */ -bliss_sampler_t *bliss_sampler_create(hash_algorithm_t alg, chunk_t seed, +bliss_sampler_t *bliss_sampler_create(ext_out_function_t alg, chunk_t seed, const bliss_param_set_t *set); #endif /** BLISS_SAMPLER_H_ @}*/ diff --git a/src/libstrongswan/plugins/bliss/bliss_utils.c b/src/libstrongswan/plugins/bliss/bliss_utils.c index 01b8af3c9..5baa1f89a 100644 --- a/src/libstrongswan/plugins/bliss/bliss_utils.c +++ b/src/libstrongswan/plugins/bliss/bliss_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Andreas Steffen + * Copyright (C) 2014-2016 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -17,7 +17,7 @@ #include <asn1/asn1.h> #include <crypto/hashers/hasher.h> -#include <crypto/mgf1/mgf1_bitspender.h> +#include <crypto/xofs/xof_bitspender.h> #include <utils/debug.h> /** @@ -56,7 +56,7 @@ void bliss_utils_round_and_drop(const bliss_param_set_t *set, /** * See header. */ -bool bliss_utils_generate_c(hash_algorithm_t alg, chunk_t data_hash, +bool bliss_utils_generate_c(ext_out_function_t alg, chunk_t data_hash, uint16_t *ud, const bliss_param_set_t *set, uint16_t *c_indices) { @@ -65,7 +65,7 @@ bool bliss_utils_generate_c(hash_algorithm_t alg, chunk_t data_hash, uint32_t index; uint8_t *seed_pos; chunk_t seed; - mgf1_bitspender_t *bitspender; + xof_bitspender_t *bitspender; seed = chunk_alloca(data_hash.len + set->n * sizeof(uint16_t)); @@ -80,7 +80,7 @@ bool bliss_utils_generate_c(hash_algorithm_t alg, chunk_t data_hash, seed_pos += sizeof(uint16_t); } - bitspender = mgf1_bitspender_create(alg, seed, FALSE); + bitspender = xof_bitspender_create(alg, seed, FALSE); if (!bitspender) { return NULL; diff --git a/src/libstrongswan/plugins/bliss/bliss_utils.h b/src/libstrongswan/plugins/bliss/bliss_utils.h index 15c5671bf..bfaf3c475 100644 --- a/src/libstrongswan/plugins/bliss/bliss_utils.h +++ b/src/libstrongswan/plugins/bliss/bliss_utils.h @@ -48,23 +48,23 @@ void bliss_utils_round_and_drop(const bliss_param_set_t *set, /** * Generate the binary challenge vector c as an array of kappa indices * - * @param alg hash algorithm to be used for the internal oracle - * @param data_hash hash of the data to be signed - * @param ud input vector ud of size n - * @param set BLISS parameter set to be used (n, n_bits, kappa) - * @param c_indices indexes of non-zero challenge coefficients + * @param alg XOF to be used for the internal oracle + * @param data_hash hash of the data to be signed + * @param ud input vector ud of size n + * @param set BLISS parameter set to be used (n, n_bits, kappa) + * @param c_indices indexes of non-zero challenge coefficients */ -bool bliss_utils_generate_c(hash_algorithm_t alg, chunk_t data_hash, +bool bliss_utils_generate_c(ext_out_function_t alg, chunk_t data_hash, uint16_t *ud, const bliss_param_set_t *set, uint16_t *c_indices); /** * Check the infinity and l2 norms of the vectors z1 and z2d << d * - * @param set BLISS parameter set - * @param z1 input vector - * @param z2d input vector - * @result TRUE if infinite and l2 norms do not exceed boundaries + * @param set BLISS parameter set + * @param z1 input vector + * @param z2d input vector + * @result TRUE if infinite and l2 norms do not exceed boundaries */ bool bliss_utils_check_norms(const bliss_param_set_t *set, int32_t *z1, int16_t *z2d); diff --git a/src/libstrongswan/plugins/chapoly/chapoly_xof.c b/src/libstrongswan/plugins/chapoly/chapoly_xof.c index db5598428..2740a55b4 100644 --- a/src/libstrongswan/plugins/chapoly/chapoly_xof.c +++ b/src/libstrongswan/plugins/chapoly/chapoly_xof.c @@ -44,6 +44,12 @@ struct private_chapoly_xof_t { chapoly_drv_t *drv; }; +METHOD(xof_t, get_type, ext_out_function_t, + private_chapoly_xof_t *this) +{ + return XOF_CHACHA20; +} + METHOD(xof_t, get_bytes, bool, private_chapoly_xof_t *this, size_t out_len, uint8_t *buffer) { @@ -53,7 +59,7 @@ METHOD(xof_t, get_bytes, bool, len = min(out_len, CHACHA_BLOCK_SIZE - this->stream_index); if (len) { - memcpy(buffer + index, this->stream + this->stream_index, len); + memcpy(buffer, this->stream + this->stream_index, len); index += len; this->stream_index += len; } @@ -151,6 +157,7 @@ chapoly_xof_t *chapoly_xof_create(ext_out_function_t algorithm) INIT(this, .public = { .xof_interface = { + .get_type = _get_type, .get_bytes = _get_bytes, .allocate_bytes = _allocate_bytes, .get_block_size = _get_block_size, diff --git a/src/libstrongswan/plugins/mgf1/Makefile.am b/src/libstrongswan/plugins/mgf1/Makefile.am new file mode 100644 index 000000000..8df227f9f --- /dev/null +++ b/src/libstrongswan/plugins/mgf1/Makefile.am @@ -0,0 +1,17 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/libstrongswan + +AM_CFLAGS = \ + $(PLUGIN_CFLAGS) + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-mgf1.la +else +plugin_LTLIBRARIES = libstrongswan-mgf1.la +endif + +libstrongswan_mgf1_la_SOURCES = \ + mgf1_plugin.h mgf1_plugin.c \ + mgf1_xof.h mgf1_xof.c + +libstrongswan_mgf1_la_LDFLAGS = -module -avoid-version diff --git a/src/libstrongswan/plugins/mgf1/mgf1_plugin.c b/src/libstrongswan/plugins/mgf1/mgf1_plugin.c new file mode 100644 index 000000000..8df3ac261 --- /dev/null +++ b/src/libstrongswan/plugins/mgf1/mgf1_plugin.c @@ -0,0 +1,81 @@ +/* + * 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 <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 "mgf1_plugin.h" +#include "mgf1_xof.h" + +#include <library.h> + +typedef struct private_mgf1_plugin_t private_mgf1_plugin_t; + +/** + * private data of mgf1_plugin + */ +struct private_mgf1_plugin_t { + + /** + * public functions + */ + mgf1_plugin_t public; +}; + +METHOD(plugin_t, get_name, char*, + private_mgf1_plugin_t *this) +{ + return "mgf1"; +} + +METHOD(plugin_t, get_features, int, + private_mgf1_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(XOF, mgf1_xof_create), + PLUGIN_PROVIDE(XOF, XOF_MGF1_SHA1), + PLUGIN_DEPENDS(HASHER, HASH_SHA1), + PLUGIN_PROVIDE(XOF, XOF_MGF1_SHA256), + PLUGIN_DEPENDS(HASHER, HASH_SHA256), + PLUGIN_PROVIDE(XOF, XOF_MGF1_SHA512), + PLUGIN_DEPENDS(HASHER, HASH_SHA512), + }; + *features = f; + return countof(f); +} + +METHOD(plugin_t, destroy, void, + private_mgf1_plugin_t *this) +{ + free(this); +} + +/* + * see header file + */ +plugin_t *mgf1_plugin_create() +{ + private_mgf1_plugin_t *this; + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, + }, + ); + + return &this->public.plugin; +} + diff --git a/src/libstrongswan/plugins/mgf1/mgf1_plugin.h b/src/libstrongswan/plugins/mgf1/mgf1_plugin.h new file mode 100644 index 000000000..50105ca29 --- /dev/null +++ b/src/libstrongswan/plugins/mgf1/mgf1_plugin.h @@ -0,0 +1,42 @@ +/* + * 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 <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 mgf1_p mgf1 + * @ingroup plugins + * + * @defgroup mgf1_plugin mgf1_plugin + * @{ @ingroup mgf1_p + */ + +#ifndef MGF1_PLUGIN_H_ +#define MGF1_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct mgf1_plugin_t mgf1_plugin_t; + +/** + * Plugin implementing the MGF1 Mask Generator Function in software. + */ +struct mgf1_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +#endif /** MGF1_PLUGIN_H_ @}*/ diff --git a/src/libstrongswan/plugins/mgf1/mgf1_xof.c b/src/libstrongswan/plugins/mgf1/mgf1_xof.c new file mode 100644 index 000000000..0f5fda952 --- /dev/null +++ b/src/libstrongswan/plugins/mgf1/mgf1_xof.c @@ -0,0 +1,285 @@ +/* + * Copyright (C) 2013-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 <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 "mgf1_xof.h" + +#include "crypto/hashers/hasher.h" +#include "utils/debug.h" + +typedef struct private_mgf1_xof_t private_mgf1_xof_t; + +/** + * Private data of an mgf1_xof_t object. + */ +struct private_mgf1_xof_t { + + /** + * Public mgf1_xof_t interface. + */ + mgf1_xof_t public; + + /** + * XOF type of the MGF1 Mask Generation Function + */ + ext_out_function_t type; + + /** + * Hasher the MGF1 Mask Generation Function is based on + */ + hasher_t *hasher; + + /** + * Is the seed hashed before using it as a seed for MGF1 ? + */ + bool hash_seed; + + /** + * Counter + */ + uint32_t counter; + + /** + * Set if counter has reached 2^32 + */ + bool overflow; + + /** + * Current state to be hashed + */ + chunk_t state; + + /** + * Position of the 4 octet counter string + */ + uint8_t *ctr_str; + + /** + * Latest hash block + */ + uint8_t buf[HASH_SIZE_SHA512]; + + /** + * Index pointing to the current position in the hash block + */ + size_t buf_index; + +}; + +METHOD(xof_t, get_type, ext_out_function_t, + private_mgf1_xof_t *this) +{ + return this->type; +} + +static bool get_next_block(private_mgf1_xof_t *this, uint8_t *buffer) +{ + /* detect overflow, set counter string and increment counter */ + if (this->overflow) + { + DBG1(DBG_LIB, "MGF1 overflow occurred"); + return FALSE; + } + htoun32(this->ctr_str, this->counter++); + if (this->counter == 0) + { + this->overflow = TRUE; + } + + /* get the next block from the hash function */ + if (!this->hasher->get_hash(this->hasher, this->state, buffer)) + { + return FALSE; + } + + return TRUE; +} + +METHOD(xof_t, get_bytes, bool, + private_mgf1_xof_t *this, size_t out_len, uint8_t *buffer) +{ + size_t index = 0, blocks, len, hash_size; + + hash_size = this->hasher->get_hash_size(this->hasher); + + /* empty the current hash block buffer first */ + len = min(out_len, hash_size - this->buf_index); + if (len) + { + memcpy(buffer, this->buf + this->buf_index, len); + index += len; + this->buf_index += len; + } + + /* copy whole hash blocks directly to output buffer */ + blocks = (out_len - index) / hash_size; + while (blocks--) + { + if (!get_next_block(this, buffer + index)) + { + return FALSE; + } + index += hash_size; + } + + /* get another hash block if some more output bytes are needed */ + len = out_len - index; + if (len) + { + if (!get_next_block(this, this->buf)) + { + return FALSE; + } + memcpy(buffer + index, this->buf, len); + this->buf_index = len; + } + + return TRUE; +} + +METHOD(xof_t, allocate_bytes, bool, + private_mgf1_xof_t *this, size_t out_len, chunk_t *chunk) +{ + *chunk = chunk_alloc(out_len); + + if (!get_bytes(this, out_len, chunk->ptr)) + { + chunk_free(chunk); + return FALSE; + } + + return TRUE; +} + +METHOD(xof_t, get_block_size, size_t, + private_mgf1_xof_t *this) +{ + return this->hasher->get_hash_size(this->hasher); +} + +METHOD(xof_t, get_seed_size, size_t, + private_mgf1_xof_t *this) +{ + return this->hasher->get_hash_size(this->hasher); +} + +METHOD(xof_t, set_seed, bool, + private_mgf1_xof_t *this, chunk_t seed) +{ + size_t hash_size, state_len; + + if (seed.len == 0) + { + DBG1(DBG_LIB, "empty seed for MGF1"); + return FALSE; + } + + /* determine state size and allocate space accordingly */ + hash_size = this->hasher->get_hash_size(this->hasher); + state_len = (this->hash_seed ? hash_size : seed.len) + 4; + chunk_clear(&this->state); + this->state = chunk_alloc(state_len); + + /* hash block buffer is empty */ + this->buf_index = hash_size; + + /* reset counter */ + this->counter = 0; + + /* determine position of the 4 octet counter string */ + this->ctr_str = this->state.ptr + state_len - 4; + + if (this->hash_seed) + { + if (!this->hasher->get_hash(this->hasher, seed, this->state.ptr)) + { + DBG1(DBG_LIB, "failed to hash seed for MGF1"); + return FALSE; + } + } + else + { + memcpy(this->state.ptr, seed.ptr, seed.len); + } + + return TRUE; +} + +METHOD(xof_t, destroy, void, + private_mgf1_xof_t *this) +{ + this->hasher->destroy(this->hasher); + chunk_clear(&this->state); + free(this); +} + +METHOD(mgf1_t, set_hash_seed, void, + private_mgf1_xof_t *this, bool yes) +{ + this->hash_seed = yes; +} + +/* + * Described in header. + */ +mgf1_xof_t *mgf1_xof_create(ext_out_function_t algorithm) +{ + private_mgf1_xof_t *this; + hash_algorithm_t hash_alg; + hasher_t *hasher; + + switch (algorithm) + { + case XOF_MGF1_SHA1: + hash_alg = HASH_SHA1; + break; + case XOF_MGF1_SHA256: + hash_alg = HASH_SHA256; + break; + case XOF_MGF1_SHA512: + hash_alg = HASH_SHA512; + break; + default: + return NULL; + } + + hasher = lib->crypto->create_hasher(lib->crypto, hash_alg); + if (!hasher) + { + DBG1(DBG_LIB, "failed to create %N hasher for MGF1", + hash_algorithm_names, hash_alg); + return NULL; + } + + INIT(this, + .public = { + .mgf1_interface = { + .xof_interface = { + .get_type = _get_type, + .get_bytes = _get_bytes, + .allocate_bytes = _allocate_bytes, + .get_block_size = _get_block_size, + .get_seed_size = _get_seed_size, + .set_seed = _set_seed, + .destroy = _destroy, + }, + .set_hash_seed = _set_hash_seed, + }, + }, + .type = algorithm, + .hasher = hasher, + ); + + return &this->public; +} diff --git a/src/libstrongswan/plugins/mgf1/mgf1_xof.h b/src/libstrongswan/plugins/mgf1/mgf1_xof.h new file mode 100644 index 000000000..9d60a807d --- /dev/null +++ b/src/libstrongswan/plugins/mgf1/mgf1_xof.h @@ -0,0 +1,49 @@ +/* + * 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 <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 mgf1_xof mgf1_xof + * @{ @ingroup crypto + */ + +#ifndef MGF1_XOF_H_ +#define MGF1_XOF_H_ + +typedef struct mgf1_xof_t mgf1_xof_t; + +#include <crypto/xofs/mgf1.h> + +/** + * Implements the PKCS#1 MGF1_XOF Mask Generation Function based on a hash + * function defined in section 10.2.1 of RFC 2437 + */ +struct mgf1_xof_t { + + /** + * mgf1_t interface for this Extended Output Function (XOF). + */ + mgf1_t mgf1_interface; +}; + +/** + * Create an mgf1_xof_t object + * + * @param algorithm XOF_MGF1_SHA1, XOF_MGF1_SHA256 or XOF_MGF1_SHA512 + * @return mgf1_xof_t object, NULL if not supported + */ +mgf1_xof_t *mgf1_xof_create(ext_out_function_t algorithm); + +#endif /** MGF1_XOF_H_ @}*/ + diff --git a/src/libstrongswan/plugins/ntru/ntru_poly.c b/src/libstrongswan/plugins/ntru/ntru_poly.c index cb11601cd..b2fca2f7f 100644 --- a/src/libstrongswan/plugins/ntru/ntru_poly.c +++ b/src/libstrongswan/plugins/ntru/ntru_poly.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Andreas Steffen + * Copyright (C) 2014-2016 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * Copyright (C) 2009-2013 Security Innovation @@ -17,7 +17,7 @@ #include "ntru_poly.h" -#include <crypto/mgf1/mgf1_bitspender.h> +#include <crypto/xofs/xof_bitspender.h> #include <utils/debug.h> #include <utils/test.h> @@ -290,8 +290,9 @@ static private_ntru_poly_t* ntru_poly_create(uint16_t N, uint16_t q, /* * Described in header. */ -ntru_poly_t *ntru_poly_create_from_seed(hash_algorithm_t alg, chunk_t seed, - uint8_t c_bits, uint16_t N, uint16_t q, +ntru_poly_t *ntru_poly_create_from_seed(ext_out_function_t mgf1_type, + chunk_t seed, uint8_t c_bits, + uint16_t N, uint16_t q, uint32_t indices_len_p, uint32_t indices_len_m, bool is_product_form) @@ -300,9 +301,9 @@ ntru_poly_t *ntru_poly_create_from_seed(hash_algorithm_t alg, chunk_t seed, int n, num_indices, index_i = 0; uint32_t index, limit; uint8_t *used; - mgf1_bitspender_t *bitspender; + xof_bitspender_t *bitspender; - bitspender = mgf1_bitspender_create(alg, seed, TRUE); + bitspender = xof_bitspender_create(mgf1_type, seed, TRUE); if (!bitspender) { return NULL; diff --git a/src/libstrongswan/plugins/ntru/ntru_poly.h b/src/libstrongswan/plugins/ntru/ntru_poly.h index 87c77103c..765b72bdd 100644 --- a/src/libstrongswan/plugins/ntru/ntru_poly.h +++ b/src/libstrongswan/plugins/ntru/ntru_poly.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Andreas Steffen + * Copyright (C) 2014-2016 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ typedef struct ntru_poly_t ntru_poly_t; #include <library.h> +#include <crypto/xofs/xof.h> /** * Implements a trinary polynomial storing the indices of non-zero coefficients @@ -63,9 +64,9 @@ struct ntru_poly_t { }; /** - * Create a trits polynomial from a seed using MGF1 with a base hash function + * Create a trits polynomial from a seed using MGF1 * - * @param alg hash algorithm to be used by MGF1 + * @param alg MGF1 algorithm used(XOF_MGF1_SHA1 or XOF_MGF_SHA256) * @param seed seed used by MGF1 to generate trits from * @param N ring dimension, number of polynomial coefficients * @param q large modulus @@ -74,7 +75,7 @@ struct ntru_poly_t { * @param indices_len_m number of indices for -1 coefficients * @param is_product_form generate multiple polynomials */ -ntru_poly_t *ntru_poly_create_from_seed(hash_algorithm_t alg, chunk_t seed, +ntru_poly_t *ntru_poly_create_from_seed(ext_out_function_t alg, chunk_t seed, uint8_t c_bits, uint16_t N, uint16_t q, uint32_t indices_len_p, uint32_t indices_len_m, diff --git a/src/libstrongswan/plugins/ntru/ntru_private_key.c b/src/libstrongswan/plugins/ntru/ntru_private_key.c index c795c9d2b..844c8baf3 100644 --- a/src/libstrongswan/plugins/ntru/ntru_private_key.c +++ b/src/libstrongswan/plugins/ntru/ntru_private_key.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Andreas Steffen + * Copyright (C) 2014-2016 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * Copyright (C) 2009-2013 Security Innovation @@ -178,7 +178,7 @@ bool ntru_check_min_weight(uint16_t N, uint8_t *t, uint16_t min_wt) METHOD(ntru_private_key_t, decrypt, bool, private_ntru_private_key_t *this, chunk_t ciphertext, chunk_t *plaintext) { - hash_algorithm_t hash_algid; + ext_out_function_t alg; size_t t_len, seed1_len, seed2_len; uint16_t *t1, *t2, *t = NULL; uint16_t mod_q_mask, q_mod_p, cmprime_len, cm_len = 0, num_zeros; @@ -206,9 +206,9 @@ METHOD(ntru_private_key_t, decrypt, bool, Mtrin = (uint8_t *)t1; M = Mtrin + this->params->N; - /* set hash algorithm based on security strength */ - hash_algid = (this->params->sec_strength_len <= 20) ? HASH_SHA1 : - HASH_SHA256; + /* set MGF1 algorithm type based on security strength */ + alg = (this->params->sec_strength_len <= 20) ? XOF_MGF1_SHA1 : + XOF_MGF1_SHA256; /* set constants */ mod_q_mask = this->params->q - 1; @@ -307,7 +307,7 @@ METHOD(ntru_private_key_t, decrypt, bool, ntru_coeffs_mod4_2_octets(this->params->N, t2, seed.ptr); /* form mask */ - mask = ntru_trits_create(this->params->N, hash_algid, seed); + mask = ntru_trits_create(this->params->N, alg, seed); if (!mask) { DBG1(DBG_LIB, "mask creation failed"); @@ -390,9 +390,8 @@ METHOD(ntru_private_key_t, decrypt, bool, /* generate cr */ DBG2(DBG_LIB, "generate polynomial r"); - r_poly = ntru_poly_create_from_seed(hash_algid, seed, - this->params->c_bits, this->params->N, - this->params->q, this->params->dF_r, + r_poly = ntru_poly_create_from_seed(alg, seed, this->params->c_bits, + this->params->N, this->params->q, this->params->dF_r, this->params->dF_r, this->params->is_product_form); if (!r_poly) { @@ -648,7 +647,7 @@ ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg, size_t t_len; uint16_t *t1, *t2, *t = NULL; uint16_t mod_q_mask; - hash_algorithm_t hash_algid; + ext_out_function_t alg; ntru_poly_t *g_poly; chunk_t seed; int i; @@ -667,14 +666,8 @@ ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg, ); /* set hash algorithm and seed length based on security strength */ - if (params->sec_strength_len <= 20) - { - hash_algid = HASH_SHA1; - } - else - { - hash_algid = HASH_SHA256; - } + alg = (params->sec_strength_len <= 20) ? XOF_MGF1_SHA1 : + XOF_MGF1_SHA256; seed =chunk_alloc(params->sec_strength_len + 8); /* get random seed for generating trinary F as a list of indices */ @@ -685,7 +678,7 @@ ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg, } DBG2(DBG_LIB, "generate polynomial F"); - this->privkey = ntru_poly_create_from_seed(hash_algid, seed, params->c_bits, + this->privkey = ntru_poly_create_from_seed(alg, seed, params->c_bits, params->N, params->q, params->dF_r, params->dF_r, params->is_product_form); @@ -729,7 +722,7 @@ ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg, } DBG2(DBG_LIB, "generate polynomial g"); - g_poly = ntru_poly_create_from_seed(hash_algid, seed, params->c_bits, + g_poly = ntru_poly_create_from_seed(alg, seed, params->c_bits, params->N, params->q, params->dg + 1, params->dg, FALSE); if (!g_poly) diff --git a/src/libstrongswan/plugins/ntru/ntru_public_key.c b/src/libstrongswan/plugins/ntru/ntru_public_key.c index 2b72d9057..36d9abf0a 100644 --- a/src/libstrongswan/plugins/ntru/ntru_public_key.c +++ b/src/libstrongswan/plugins/ntru/ntru_public_key.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Andreas Steffen + * Copyright (C) 2014-2016 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * Copyright (C) 2009-2013 Security Innovation @@ -102,7 +102,7 @@ extern bool ntru_check_min_weight(uint16_t N, uint8_t *t, uint16_t min_wt); METHOD(ntru_public_key_t, encrypt, bool, private_ntru_public_key_t *this, chunk_t plaintext, chunk_t *ciphertext) { - hash_algorithm_t hash_algid; + ext_out_function_t alg; size_t t_len, seed1_len, seed2_len; uint16_t *t1, *t = NULL; uint8_t b[MAX_SEC_STRENGTH_LEN]; @@ -139,8 +139,8 @@ METHOD(ntru_public_key_t, encrypt, bool, M = Mtrin + this->params->N; /* set hash algorithm based on security strength */ - hash_algid = (this->params->sec_strength_len <= 20) ? HASH_SHA1 : - HASH_SHA256; + alg = (this->params->sec_strength_len <= 20) ? XOF_MGF1_SHA1 : + XOF_MGF1_SHA256; /* set constants */ mod_q_mask = this->params->q - 1; @@ -173,7 +173,7 @@ METHOD(ntru_public_key_t, encrypt, bool, seed.len = seed2_len; DBG2(DBG_LIB, "generate polynomial r"); - r_poly = ntru_poly_create_from_seed(hash_algid, seed, this->params->c_bits, + r_poly = ntru_poly_create_from_seed(alg, seed, this->params->c_bits, this->params->N, this->params->q, this->params->dF_r, this->params->dF_r, this->params->is_product_form); @@ -191,7 +191,7 @@ METHOD(ntru_public_key_t, encrypt, bool, seed.len = seed1_len; /* form mask */ - mask = ntru_trits_create(this->params->N, hash_algid, seed); + mask = ntru_trits_create(this->params->N, alg, seed); if (!mask) { DBG1(DBG_LIB, "mask creation failed"); diff --git a/src/libstrongswan/plugins/ntru/ntru_trits.c b/src/libstrongswan/plugins/ntru/ntru_trits.c index 57b3532ef..0bbbcc178 100644 --- a/src/libstrongswan/plugins/ntru/ntru_trits.c +++ b/src/libstrongswan/plugins/ntru/ntru_trits.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2014 Andreas Steffen + * Copyright (C) 2013-2016 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -16,7 +16,7 @@ #include "ntru_trits.h" #include "ntru_convert.h" -#include <crypto/mgf1/mgf1_bitspender.h> +#include <crypto/xofs/xof_bitspender.h> #include <utils/debug.h> #include <utils/test.h> @@ -67,14 +67,15 @@ METHOD(ntru_trits_t, destroy, void, /* * Described in header. */ -ntru_trits_t *ntru_trits_create(size_t len, hash_algorithm_t alg, chunk_t seed) +ntru_trits_t *ntru_trits_create(size_t len, ext_out_function_t alg, + chunk_t seed) { private_ntru_trits_t *this; uint8_t octet, buf[5], *trits; size_t trits_needed; - mgf1_bitspender_t *bitspender; + xof_bitspender_t *bitspender; - bitspender = mgf1_bitspender_create(alg, seed, TRUE); + bitspender = xof_bitspender_create(alg, seed, TRUE); if (!bitspender) { return NULL; diff --git a/src/libstrongswan/plugins/ntru/ntru_trits.h b/src/libstrongswan/plugins/ntru/ntru_trits.h index 524c51bac..e489aae7a 100644 --- a/src/libstrongswan/plugins/ntru/ntru_trits.h +++ b/src/libstrongswan/plugins/ntru/ntru_trits.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Andreas Steffen + * Copyright (C) 2013-2016 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ typedef struct ntru_trits_t ntru_trits_t; #include <library.h> +#include <crypto/xofs/xof.h> /** * Implements an array of trinary elements (trits) @@ -52,10 +53,11 @@ struct ntru_trits_t { * Create a trits array from a seed using MGF1 with a base hash function * * @param size size of the trits array - * @param alg hash algorithm to be used by MGF1 + * @param alg MGF1 algorithm used (XOF_MGF1_SHA1 or XOF_MGF_SHA256) * @param seed seed used by MGF1 to generate trits from */ -ntru_trits_t *ntru_trits_create(size_t size, hash_algorithm_t alg, chunk_t seed); +ntru_trits_t *ntru_trits_create(size_t size, ext_out_function_t alg, + chunk_t seed); #endif /** NTRU_TRITS_H_ @}*/ diff --git a/src/libstrongswan/plugins/sha3/sha3_shake.c b/src/libstrongswan/plugins/sha3/sha3_shake.c index fef26bb52..0f1af39f5 100644 --- a/src/libstrongswan/plugins/sha3/sha3_shake.c +++ b/src/libstrongswan/plugins/sha3/sha3_shake.c @@ -46,6 +46,11 @@ struct private_sha3_shake_t { }; +METHOD(xof_t, get_type, ext_out_function_t, + private_sha3_shake_t *this) +{ + return this->algorithm; +} METHOD(xof_t, get_bytes, bool, private_sha3_shake_t *this, size_t out_len, uint8_t *buffer) @@ -114,6 +119,7 @@ sha3_shake_t* sha3_shake_create(ext_out_function_t algorithm) INIT(this, .public = { .xof_interface = { + .get_type = _get_type, .get_bytes = _get_bytes, .allocate_bytes = _allocate_bytes, .get_block_size = _get_block_size, diff --git a/src/libstrongswan/tests/suites/test_mgf1.c b/src/libstrongswan/tests/suites/test_mgf1.c index 9388b95d4..6945f5c7f 100644 --- a/src/libstrongswan/tests/suites/test_mgf1.c +++ b/src/libstrongswan/tests/suites/test_mgf1.c @@ -17,11 +17,12 @@ #include <tests/utils/test_rng.h> #include <utils/test.h> -#include <crypto/mgf1/mgf1.h> -#include <crypto/mgf1/mgf1_bitspender.h> +#include <crypto/xofs/xof.h> +#include <crypto/xofs/xof_bitspender.h> +#include <crypto/xofs/mgf1.h> typedef struct { - hash_algorithm_t alg; + ext_out_function_t alg; size_t hash_size; size_t ml1, ml2, ml3, seed_len; chunk_t seed; @@ -34,7 +35,7 @@ typedef struct { * MGF1 Mask Generation Function Test Vectors */ mgf1_test_t mgf1_tests[] = { - { HASH_SHA1, 20, 60, 20, 15, 24, + { XOF_MGF1_SHA1, 20, 60, 20, 15, 24, chunk_from_chars( 0xED, 0xA5, 0xC3, 0xBC, 0xAF, 0xB3, 0x20, 0x7D, 0x14, 0xA1, 0x54, 0xF7, 0x8B, 0x37, 0xF2, 0x8D, @@ -73,7 +74,7 @@ mgf1_test_t mgf1_tests[] = { { 0, 0, 0, 4, 1, 1, 46, 103, 38, 411, 848, 57, 3540, 4058, 12403, 0x63, 0x2B, 0xC9, 0x17, 0x56, 669409, 0xA407A43B }, }, - { HASH_SHA256, 32, 64, 32, 33, 40, + { XOF_MGF1_SHA256, 32, 64, 32, 33, 40, chunk_from_chars( 0x52, 0xC5, 0xDD, 0x1E, 0xEF, 0x76, 0x1B, 0x53, 0x08, 0xE4, 0x86, 0x3F, 0x91, 0x12, 0x98, 0x69, @@ -127,6 +128,7 @@ mgf1_test_t mgf1_tests[] = { START_TEST(mgf1_test_mgf1) { + xof_t *xof; mgf1_t *mgf1; chunk_t mask, mask1, mask2, mask3; @@ -137,72 +139,88 @@ START_TEST(mgf1_test_mgf1) mask2.len = mgf1_tests[_i].ml2; mask3.len = mgf1_tests[_i].ml3; - mgf1 = mgf1_create(HASH_UNKNOWN, mgf1_tests[_i].seed, TRUE); - ck_assert(mgf1 == NULL); + /* unknown XOF */ + xof = lib->crypto->create_xof(lib->crypto, XOF_UNDEFINED); + ck_assert(xof == NULL); - mgf1 = mgf1_create(mgf1_tests[_i].alg, chunk_empty, TRUE); - ck_assert(mgf1 == NULL); + /* create MGF1 XOF */ + xof = lib->crypto->create_xof(lib->crypto, mgf1_tests[_i].alg); + ck_assert(xof); - /* return mask in allocated chunk */ - mgf1 = mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE); - ck_assert(mgf1); + /* hash the seed */ + mgf1 = (mgf1_t*)xof; + mgf1->set_hash_seed(mgf1, TRUE); - /* check hash size */ - ck_assert(mgf1->get_hash_size(mgf1) == mgf1_tests[_i].hash_size); + /* check MGF1 type */ + ck_assert(xof->get_type(xof) == mgf1_tests[_i].alg); - /* get zero number of octets */ - ck_assert(mgf1->allocate_mask(mgf1, 0, &mask)); + /* check seed size */ + ck_assert(xof->get_seed_size(xof) == mgf1_tests[_i].hash_size); + + /* check block size */ + ck_assert(xof->get_block_size(xof) == mgf1_tests[_i].hash_size); + + /* empty seed */ + ck_assert(!xof->set_seed(xof, chunk_empty)); + + /* initialize MGF1 with non-empty seed */ + ck_assert(xof->set_seed(xof, mgf1_tests[_i].seed)); + + /* allocate zero number of octets */ + ck_assert(xof->allocate_bytes(xof, 0, &mask)); ck_assert(mask.len == 0 && mask.ptr == NULL); - /* get non-zero number of octets */ - ck_assert(mgf1->allocate_mask(mgf1, mgf1_tests[_i].mask.len, &mask)); + /* allocate non-zero number of octets */ + ck_assert(xof->allocate_bytes(xof, mgf1_tests[_i].mask.len, &mask)); ck_assert(chunk_equals(mask, mgf1_tests[_i].mask)); - mgf1->destroy(mgf1); + + /* re-initialize MGF1 with non-empty seed */ + ck_assert(xof->set_seed(xof, mgf1_tests[_i].seed)); /* copy mask to pre-allocated buffer */ - mgf1 = mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE); - ck_assert(mgf1); - ck_assert(mgf1->get_mask(mgf1, mgf1_tests[_i].mask.len, mask.ptr)); + ck_assert(xof->get_bytes(xof, mgf1_tests[_i].mask.len, mask.ptr)); ck_assert(chunk_equals(mask, mgf1_tests[_i].mask)); - mgf1->destroy(mgf1); - /* get mask in batches without hashing the seed */ - mgf1 = mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].hashed_seed, FALSE); - ck_assert(mgf1); + /* do not hash the seed */ + mgf1->set_hash_seed(mgf1, FALSE); + + /* re-initialize MGF1 with non-empty seed */ + ck_assert(xof->set_seed(xof, mgf1_tests[_i].hashed_seed)); /* first batch */ - ck_assert(mgf1->get_mask(mgf1, mask1.len, mask.ptr)); + ck_assert(xof->get_bytes(xof, mask1.len, mask.ptr)); mask.len = mask1.len; ck_assert(chunk_equals(mask, mask1)); /* second batch */ - ck_assert(mgf1->get_mask(mgf1, mask2.len, mask.ptr)); + ck_assert(xof->get_bytes(xof, mask2.len, mask.ptr)); mask.len = mask2.len; ck_assert(chunk_equals(mask, mask2)); /* third batch */ - ck_assert(mgf1->get_mask(mgf1, mask3.len, mask.ptr)); + ck_assert(xof->get_bytes(xof, mask3.len, mask.ptr)); mask.len = mask3.len; ck_assert(chunk_equals(mask, mask3)); - mgf1->destroy(mgf1); + /* clean up */ + xof->destroy(xof); chunk_free(&mask); } END_TEST START_TEST(mgf1_test_bitspender) { - mgf1_bitspender_t *bitspender; + xof_bitspender_t *bitspender; uint32_t bits; uint8_t byte; int j; - bitspender = mgf1_bitspender_create(HASH_UNKNOWN, - mgf1_tests[_i].hashed_seed, FALSE); + bitspender = xof_bitspender_create(XOF_UNDEFINED, + mgf1_tests[_i].hashed_seed, FALSE); ck_assert(bitspender == NULL); - bitspender = mgf1_bitspender_create(mgf1_tests[_i].alg, - mgf1_tests[_i].hashed_seed, FALSE); + bitspender = xof_bitspender_create(mgf1_tests[_i].alg, + mgf1_tests[_i].hashed_seed, FALSE); ck_assert(bitspender); for (j = 0; j < 15; j++) diff --git a/src/libstrongswan/tests/suites/test_ntru.c b/src/libstrongswan/tests/suites/test_ntru.c index 0a6d24d04..0b432e24c 100644 --- a/src/libstrongswan/tests/suites/test_ntru.c +++ b/src/libstrongswan/tests/suites/test_ntru.c @@ -17,7 +17,7 @@ #include <tests/utils/test_rng.h> #include <utils/test.h> -#include <crypto/mgf1/mgf1.h> +#include <crypto/xofs/xof.h> #include <plugins/ntru/ntru_drbg.h> #include <plugins/ntru/ntru_trits.h> #include <plugins/ntru/ntru_poly.h> @@ -28,10 +28,10 @@ IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_drbg_create, ntru_drbg_t*, uint32_t strength, chunk_t pers_str, rng_t *entropy) IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_trits_create, ntru_trits_t*, - size_t len, hash_algorithm_t alg, chunk_t seed) + size_t len, ext_out_function_t alg, chunk_t seed) IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_poly_create_from_seed, ntru_poly_t*, - hash_algorithm_t alg, chunk_t seed, uint8_t c_bits, + ext_out_function_t alg, chunk_t seed, uint8_t c_bits, uint16_t N, uint16_t q, uint32_t indices_len_p, uint32_t indices_len_m, bool is_product_form) @@ -329,7 +329,7 @@ typedef struct { } poly_test_t; typedef struct { - hash_algorithm_t alg; + ext_out_function_t alg; size_t hash_size; size_t seed_len; chunk_t seed; @@ -384,7 +384,7 @@ uint16_t indices_ees1171ep1[] = { * Trits and Polynomial Test Vectors */ static trits_test_t trits_tests[] = { - { HASH_SHA1, 20, 24, + { XOF_MGF1_SHA1, 20, 24, chunk_from_chars( 0xED, 0xA5, 0xC3, 0xBC, 0xAF, 0xB3, 0x20, 0x7D, 0x14, 0xA1, 0x54, 0xF7, 0x8B, 0x37, 0xF2, 0x8D, @@ -432,7 +432,7 @@ static trits_test_t trits_tests[] = { } } }, - { HASH_SHA256, 32, 40, + { XOF_MGF1_SHA256, 32, 40, chunk_from_chars( 0x52, 0xC5, 0xDD, 0x1E, 0xEF, 0x76, 0x1B, 0x53, 0x08, 0xE4, 0x86, 0x3F, 0x91, 0x12, 0x98, 0x69, @@ -501,7 +501,7 @@ START_TEST(test_ntru_trits) chunk_t trits; mask = TEST_FUNCTION(ntru, ntru_trits_create, trits_tests[_i].trits.len, - HASH_UNKNOWN, trits_tests[_i].seed); + XOF_UNDEFINED, trits_tests[_i].seed); ck_assert(mask == NULL); mask = TEST_FUNCTION(ntru, ntru_trits_create, trits_tests[_i].trits.len, @@ -539,7 +539,7 @@ START_TEST(test_ntru_poly) seed.len = trits_tests[_i].seed_len; p = &trits_tests[_i].poly_test[0]; - poly = TEST_FUNCTION(ntru, ntru_poly_create_from_seed, HASH_UNKNOWN, seed, + poly = TEST_FUNCTION(ntru, ntru_poly_create_from_seed, XOF_UNDEFINED, seed, p->c_bits, p->N, p->q, p->indices_len, p->indices_len, p->is_product_form); ck_assert(poly == NULL); |