Implemented get_byte() method for mgf1_bitspender class
authorAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 10 Nov 2014 06:56:28 +0000 (07:56 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Sat, 29 Nov 2014 13:51:16 +0000 (14:51 +0100)
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.

src/libstrongswan/crypto/mgf1/mgf1_bitspender.c
src/libstrongswan/crypto/mgf1/mgf1_bitspender.h
src/libstrongswan/plugins/ntru/ntru_poly.c
src/libstrongswan/tests/suites/test_mgf1.c

index 1b3533f..d11a717 100644 (file)
@@ -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,
index a748695..a2d796c 100644 (file)
@@ -15,7 +15,7 @@
 
 /**
  * @defgroup mgf1_bitspender mgf1_bitspender
- * @{ @ingroup bliss_p
+ * @{ @ingroup mgf1_p
  */
 
 #ifndef MGF1_BITSPENDER_H_
 
 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
index b5b3898..cb11601 100644 (file)
@@ -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);
index 14e56e6..a60666f 100644 (file)
@@ -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);
 }