Use MGF1 with SHA-512 as BLISS random oracle
authorAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 27 Jul 2015 12:50:14 +0000 (14:50 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 27 Jul 2015 20:09:08 +0000 (22:09 +0200)
NEWS
src/libstrongswan/plugins/bliss/bliss_private_key.c
src/libstrongswan/plugins/bliss/bliss_public_key.c
src/libstrongswan/plugins/bliss/bliss_utils.c
src/libstrongswan/plugins/bliss/bliss_utils.h

diff --git a/NEWS b/NEWS
index e054024..9384879 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,11 @@ strongswan-5.3.3
 - The vici interface now supports the configuration of auxiliary certification
   authority information as CRL and OCSP URIs
  
+- In the bliss plugin the c_indices derivation using a SHA-512 based random oracle
+  has been fixed, generalized and standardized by employing the MGF1 mask generation
+  function with SHA-512. As a consequence BLISS signatures unsing the improved oracle
+  are not compatible with the earlier implementation.
 
 strongswan-5.3.2
 ----------------
index e1064d2..1386eeb 100644 (file)
@@ -168,7 +168,7 @@ 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;
+       hash_algorithm_t mgf1_alg, 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;
@@ -185,7 +185,7 @@ static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg,
        /* Initialize signature */
        *signature = chunk_empty;
 
-       /* Create data hash */
+       /* Create data hash using configurable hash algorithm */
        hasher = lib->crypto->create_hasher(lib->crypto, alg);
        if (!hasher)
        {
@@ -200,13 +200,6 @@ static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg,
        }
        hasher->destroy(hasher);
 
-       /* Create SHA512 hasher for c_indices oracle */
-       hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA512);
-       if (!hasher)
-       {
-               return FALSE;
-       }
-
        /* Set MGF1 hash algorithm and seed length based on security strength */
        if (this->set->strength > 160)
        {
@@ -223,10 +216,12 @@ static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg,
        rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
        if (!rng)
        {
-               hasher->destroy(hasher);
                return FALSE;
        }
 
+       /* MGF1 hash algorithm to be used for random oracle */
+       oracle_alg = HASH_SHA512;
+
        /* Initialize a couple of needed variables */
        n  = this->set->n;
        q  = this->set->q;
@@ -360,7 +355,7 @@ static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg,
                        DBG3(DBG_LIB, "%3d  %6d   %4d", i, u[i], ud[i]);
                }
 
-               if (!bliss_utils_generate_c(hasher, data_hash, ud, n, this->set->kappa,
+               if (!bliss_utils_generate_c(oracle_alg, data_hash, ud, this->set,
                                                                        c_indices))
                {
                        goto end;
@@ -495,7 +490,6 @@ static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg,
 end:
        /* cleanup */
        DESTROY_IF(sampler);
-       hasher->destroy(hasher);
        sig->destroy(sig);
        fft->destroy(fft);
        rng->destroy(rng);
index 0175b0f..2b305f6 100644 (file)
@@ -70,11 +70,12 @@ 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;
        bliss_fft_t *fft;
        bliss_signature_t *sig;
        bool success = FALSE;
 
-       /* Create data hash */
+       /* Create data hash using configurable hash algorithm */
        hasher = lib->crypto->create_hasher(lib->crypto, alg);
        if (!hasher )
        {
@@ -89,28 +90,22 @@ static bool verify_bliss(private_bliss_public_key_t *this, hash_algorithm_t alg,
        }
        hasher->destroy(hasher);
 
-       /* Create SHA512 hasher for c_indices oracle */
-       hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA512);
-       if (!hasher)
-       {
-               return FALSE;
-       }
-
        sig = bliss_signature_create_from_data(this->set, signature);
        if (!sig)
        {
-               hasher->destroy(hasher);
                return FALSE;
        }
        sig->get_parameters(sig, &z1, &z2d, &c_indices);
 
        if (!bliss_utils_check_norms(this->set, z1, z2d))
        {
-               hasher->destroy(hasher);
                sig->destroy(sig);
                return FALSE;
        }
 
+       /* MGF1 hash algorithm to be used for random oracle */
+       oracle_alg = HASH_SHA512;
+
        /* Initialize a couple of needed variables */
        n  = this->set->n;
        q  = this->set->q;
@@ -165,8 +160,7 @@ static bool verify_bliss(private_bliss_public_key_t *this, hash_algorithm_t alg,
                DBG3(DBG_LIB, "%3d  %6d   %4d  %4d", i, u[i], ud[i], z2d[i]);
        }
 
-       if (!bliss_utils_generate_c(hasher, data_hash, ud, n, this->set->kappa,
-                                                               indices))
+       if (!bliss_utils_generate_c(oracle_alg, data_hash, ud, this->set, indices))
        {
                goto end;
        }
@@ -183,7 +177,6 @@ static bool verify_bliss(private_bliss_public_key_t *this, hash_algorithm_t alg,
 
 end:
        /* cleanup */
-       hasher->destroy(hasher);
        sig->destroy(sig);
        fft->destroy(fft);
        free(az);
index 85bd7df..5e313ff 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <asn1/asn1.h>
 #include <crypto/hashers/hasher.h>
+#include <crypto/mgf1/mgf1_bitspender.h>
 #include <utils/debug.h>
 
 /**
@@ -54,64 +55,62 @@ void bliss_utils_round_and_drop(bliss_param_set_t *set, int32_t *x, int16_t *xd)
 /**
  * See header.
  */
-bool bliss_utils_generate_c(hasher_t *hasher, chunk_t data_hash, uint16_t *ud,
-                                                       int n, uint16_t kappa, uint16_t *c_indices)
+bool bliss_utils_generate_c(hash_algorithm_t alg, chunk_t data_hash,
+                                                       uint16_t *ud, bliss_param_set_t *set,
+                                                       uint16_t *c_indices)
 {
-       int i, index_found, rounds;
-       uint16_t index;
-       uint8_t hash[HASH_SIZE_SHA512], un16_buf[2];
-       chunk_t un16 = { un16_buf, 2 };
-       bool index_taken[n];
+       int i, index_trials = 0, index_found = 0;
+       bool index_taken[set->n];
+       uint32_t index;
+       uint8_t *seed_pos;
+       chunk_t seed;
+       mgf1_bitspender_t *bitspender;
 
-       for (i = 0; i < n; i++)
+       seed = chunk_alloca(data_hash.len + set->n * sizeof(uint16_t));
+
+       /* the data hash makes up the first part of the oracle seed */
+       memcpy(seed.ptr, data_hash.ptr, data_hash.len);
+       seed_pos = seed.ptr + data_hash.len;
+
+       /* followed by the n elements of the ud vector in network order */
+       for (i = 0; i < set->n; i++)
        {
-               index_taken[i] = FALSE;
+               htoun16(seed_pos, ud[i]);
+               seed_pos += sizeof(uint16_t);
        }
-       index_found = 0;
 
-       for (rounds = 0; rounds < 0x10000; rounds++)
+       bitspender = mgf1_bitspender_create(alg, seed, FALSE);
+       if (!bitspender)
        {
-               /* hash data */
-               if (!hasher->get_hash(hasher, data_hash, NULL))
-               {
-                       return FALSE;
-               }
+           return NULL;
+       }
 
-               /* followed by the ud vector */
-               for (i = 0; i < n; i++)
-               {
-                       htoun16(un16_buf, ud[i]);
-                       if (!hasher->get_hash(hasher, un16, NULL))
-                       {
-                               return FALSE;
-                       }
-               }
+       for (i = 0; i < set->n; i++)
+       {
+               index_taken[i] = FALSE;
+       }
 
-               /* hash the round iteration */
-               htoun16(un16_buf, rounds);
-               if (!hasher->get_hash(hasher, un16, hash))
-               {
-                       return FALSE;
-               }
+       DBG3(DBG_LIB, " i  c_index[i]");
+       while (bitspender->get_bits(bitspender, set->n_bits, &index))
+       {
+               index_trials++;
 
-               for (i = 0; i < HASH_SIZE_SHA512; i += 2)
+               if (!index_taken[index])
                {
-                       index = untoh16(&hash[i]) % n;
+                       DBG3(DBG_LIB, "%2u %8u", index_found, index);
+                       c_indices[index_found++] = index;
+                       index_taken[index] = TRUE;
 
-                       if (!index_taken[index])
+                       if (index_found == set->kappa)
                        {
-                               c_indices[index_found++] = index;
-                               index_taken[index] = TRUE;
-
-                               if (index_found == kappa)
-                               {
-                                       return TRUE;
-                               }
+                               DBG3(DBG_LIB, "%2d  index trials", index_trials);
+                               bitspender->destroy(bitspender);
+                               return TRUE;
                        }
                }
        }
-       DBG1(DBG_LIB, "aborted c_indices generation after 2^16 rounds");
 
+       bitspender->destroy(bitspender);
        return FALSE;
 }
 
index 063fd91..156968d 100644 (file)
@@ -47,15 +47,15 @@ void bliss_utils_round_and_drop(bliss_param_set_t *set,     int32_t *x, int16_t *xd)
 /**
  * Generate the binary challenge vector c as an array of kappa indices
  *
- * @param hasher       hasher used as an oracle
+ * @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 n                    size of input vector ud
- * @param kappa                parameter kappa
+ * @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(hasher_t *hasher, chunk_t data_hash, uint16_t *ud,
-                                                       int n, uint16_t kappa, uint16_t *c_indices);
+bool bliss_utils_generate_c(hash_algorithm_t alg, chunk_t data_hash,
+                                                       uint16_t *ud, bliss_param_set_t *set,
+                                                       uint16_t *c_indices);
 
 /**
  * Check the infinity and l2 norms of the vectors z1 and z2d << d