From: Andreas Steffen Date: Mon, 10 Nov 2014 06:56:28 +0000 (+0100) Subject: Implemented get_byte() method for mgf1_bitspender class X-Git-Tag: 5.2.2dr1~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=72bb7eec9c626859c46ce9d8d81dc89854eacb4d;p=thirdparty%2Fstrongswan.git Implemented get_byte() method for mgf1_bitspender class The new get_byte() method returns a pseudo-random byte at a time. Changed the get_bits() interface to the same interface as get_byte(). Updated the mgf1 unit-tests accordingly. --- diff --git a/src/libstrongswan/crypto/mgf1/mgf1_bitspender.c b/src/libstrongswan/crypto/mgf1/mgf1_bitspender.c index 1b3533f138..d11a717f1e 100644 --- a/src/libstrongswan/crypto/mgf1/mgf1_bitspender.c +++ b/src/libstrongswan/crypto/mgf1/mgf1_bitspender.c @@ -62,19 +62,30 @@ struct private_mgf1_bitspender_t { * Number of available bits */ int bits_left; + + /** + * Byte storage (accomodates up to 4 bytes) + */ + uint8_t bytes[4]; + + /** + * Number of available bytes + */ + int bytes_left; + }; -METHOD(mgf1_bitspender_t, get_bits, uint32_t, - private_mgf1_bitspender_t *this, int bits_needed) +METHOD(mgf1_bitspender_t, get_bits, bool, + private_mgf1_bitspender_t *this, int bits_needed, uint32_t *bits) { - uint32_t bits = 0x00000000; int bits_now; - if (bits_needed > 31) + if (bits_needed > 32) { /* too many bits requested */ - return MGF1_BITSPENDER_ERROR; + return FALSE; } + *bits = 0x00000000; while (bits_needed) { @@ -87,7 +98,7 @@ METHOD(mgf1_bitspender_t, get_bits, uint32_t, this->octets)) { /* no block available */ - return MGF1_BITSPENDER_ERROR; + return FALSE; } this->octets_left = this->hash_len; this->octets_count += this->hash_len; @@ -102,22 +113,46 @@ METHOD(mgf1_bitspender_t, get_bits, uint32_t, bits_now = this->bits_left; this->bits_left = 0; bits_needed -= bits_now; - bits <<= bits_now; - bits |= this->bits; + *bits <<= bits_now; + *bits |= this->bits; } else { bits_now = bits_needed; this->bits_left -= bits_needed; bits_needed = 0; - bits <<= bits_now; - bits |= this->bits >> this->bits_left; + *bits <<= bits_now; + *bits |= this->bits >> this->bits_left; this->bits &= 0xffffffff >> (32 - this->bits_left); } } - return bits; + 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) @@ -148,6 +183,7 @@ mgf1_bitspender_t *mgf1_bitspender_create(hash_algorithm_t alg, chunk_t seed, INIT(this, .public = { .get_bits = _get_bits, + .get_byte = _get_byte, .destroy = _destroy, }, .mgf1 = mgf1, diff --git a/src/libstrongswan/crypto/mgf1/mgf1_bitspender.h b/src/libstrongswan/crypto/mgf1/mgf1_bitspender.h index a748695e50..a2d796cda8 100644 --- a/src/libstrongswan/crypto/mgf1/mgf1_bitspender.h +++ b/src/libstrongswan/crypto/mgf1/mgf1_bitspender.h @@ -15,7 +15,7 @@ /** * @defgroup mgf1_bitspender mgf1_bitspender - * @{ @ingroup bliss_p + * @{ @ingroup mgf1_p */ #ifndef MGF1_BITSPENDER_H_ @@ -26,20 +26,27 @@ typedef struct mgf1_bitspender_t mgf1_bitspender_t; -#define MGF1_BITSPENDER_ERROR 0xffffffff - /** - * Generates a given number of pseudo-random bits at a time using MFG1 + * Generates a given number of pseudo-random bits at a time using MGF1 */ struct mgf1_bitspender_t { /** * Get pseudo-random bits * - * @param bits_needed Number of needed bits (1..31) - * @result Return between 1 and 31 pseudo-random bits + * @param bits_needed Number of needed bits (1..32) + * @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); + + /** + * Get a pseudo-random byte + * + * @param byte Pseudo-random byte + * @result FALSE if internal MGF1 error occurred */ - uint32_t (*get_bits)(mgf1_bitspender_t *this, int bits_needed); + bool (*get_byte)(mgf1_bitspender_t *this, uint8_t *byte); /** * Destroy mgf1_bitspender_t object diff --git a/src/libstrongswan/plugins/ntru/ntru_poly.c b/src/libstrongswan/plugins/ntru/ntru_poly.c index b5b3898f23..cb11601cdb 100644 --- a/src/libstrongswan/plugins/ntru/ntru_poly.c +++ b/src/libstrongswan/plugins/ntru/ntru_poly.c @@ -323,8 +323,7 @@ ntru_poly_t *ntru_poly_create_from_seed(hash_algorithm_t alg, chunk_t seed, /* generate a random candidate index with a size of c_bits */ do { - index = bitspender->get_bits(bitspender, c_bits); - if (index == MGF1_BITSPENDER_ERROR) + if (!bitspender->get_bits(bitspender, c_bits, &index)) { bitspender->destroy(bitspender); destroy(this); diff --git a/src/libstrongswan/tests/suites/test_mgf1.c b/src/libstrongswan/tests/suites/test_mgf1.c index 14e56e6d0f..a60666f0e0 100644 --- a/src/libstrongswan/tests/suites/test_mgf1.c +++ b/src/libstrongswan/tests/suites/test_mgf1.c @@ -27,7 +27,7 @@ typedef struct { chunk_t seed; chunk_t hashed_seed; chunk_t mask; - uint32_t bits[15]; + uint32_t bits[20]; } mgf1_test_t; /** @@ -70,7 +70,8 @@ mgf1_test_t mgf1_tests[] = { 0x4D, 0x29, 0x0B, 0xCE, 0xA6, 0x21, 0xB5, 0x5C, 0x71, 0x66, 0x2F, 0x70, 0x35, 0xD8, 0x8A, 0x92, 0x33, 0xF0, 0x16, 0xD4, 0x0E, 0x43, 0x8A, 0x14), - { 0, 0, 0, 4, 1, 1, 46, 103, 38, 411, 848, 57, 3540, 4058, 12403 }, + { 0, 0, 0, 4, 1, 1, 46, 103, 38, 411, 848, 57, 3540, 4058, 12403, + 0x63, 0x2B, 0xC9, 0x17, 0x56 }, }, { HASH_SHA256, 32, 64, 32, 33, 40, chunk_from_chars( @@ -119,7 +120,8 @@ mgf1_test_t mgf1_tests[] = { 0x2B, 0x3C, 0x91, 0x3A, 0x32, 0xF8, 0xB2, 0xC6, 0x44, 0x4D, 0xCD, 0xB6, 0x54, 0x5F, 0x81, 0x95, 0x59, 0xA1, 0xE5, 0x4E, 0xA5, 0x0A, 0x4A, 0x42), - { 0, 1, 3, 4, 4, 12, 32, 36, 253, 331, 2, 1640, 503, 6924, 580 } + { 0, 1, 3, 4, 4, 12, 32, 36, 253, 331, 2, 1640, 503, 6924, 580, + 0xCB, 0x35, 0x3C, 0xDC, 0xAD } } }; @@ -192,6 +194,7 @@ START_TEST(mgf1_test_bitspender) { mgf1_bitspender_t *bitspender; uint32_t bits; + uint8_t byte; int j; bitspender = mgf1_bitspender_create(HASH_UNKNOWN, @@ -204,13 +207,20 @@ START_TEST(mgf1_test_bitspender) for (j = 0; j < 15; j++) { - bits = bitspender->get_bits(bitspender, j); + ck_assert(bitspender->get_bits(bitspender, j, &bits)); DBG1(DBG_LIB, "bits[%d] = %u, bits = %u", j, mgf1_tests[_i].bits[j], bits); ck_assert(bits == mgf1_tests[_i].bits[j]); } - bits = bitspender->get_bits(bitspender, 32); - ck_assert(bits == MGF1_BITSPENDER_ERROR); + ck_assert(!bitspender->get_bits(bitspender, 33, &bits)); + + for (j = 15; j < 20; j++) + { + ck_assert(bitspender->get_byte(bitspender, &byte)); + DBG1(DBG_LIB, "bits[%d] = 0x%02x, byte = 0x%02x", j, + mgf1_tests[_i].bits[j], byte); + ck_assert(byte == mgf1_tests[_i].bits[j]); + } bitspender->destroy(bitspender); }