Browse Source

improve fortuna_import()

This makes fortuna_import() kinda compliant to the "Update seed file"
behavior of the original paper.
It differs from the original behavior in that it allows to import
seed files which are larger	than 64 bytes.
Steffen Jaeckel 7 years ago
parent
commit
39d4a14c29
1 changed files with 48 additions and 13 deletions
  1. 48 13
      src/prngs/fortuna.c

+ 48 - 13
src/prngs/fortuna.c

@@ -124,6 +124,46 @@ static int _fortuna_reseed(prng_state *prng)
    return CRYPT_OK;
 }
 
+/**
+  "Update Seed File"-compliant update of K
+
+  @param in       The PRNG state
+  @param inlen    Size of the state
+  @param prng     The PRNG to import
+  @return CRYPT_OK if successful
+*/
+static int _fortuna_update_seed(const unsigned char *in, unsigned long inlen, prng_state *prng)
+{
+   int           err;
+   unsigned char tmp[MAXBLOCKSIZE];
+   hash_state    md;
+
+   LTC_MUTEX_LOCK(&prng->lock);
+   /* new K = LTC_SHA256(K || in) */
+   sha256_init(&md);
+   if ((err = sha256_process(&md, prng->fortuna.K, 32)) != CRYPT_OK) {
+      sha256_done(&md, tmp);
+      goto LBL_UNLOCK;
+   }
+   if ((err = sha256_process(&md, in, inlen)) != CRYPT_OK) {
+      sha256_done(&md, tmp);
+      goto LBL_UNLOCK;
+   }
+   /* finish key */
+   if ((err = sha256_done(&md, prng->fortuna.K)) != CRYPT_OK) {
+      goto LBL_UNLOCK;
+   }
+   _fortuna_update_iv(prng);
+
+LBL_UNLOCK:
+   LTC_MUTEX_UNLOCK(&prng->lock);
+#ifdef LTC_CLEAN_STACK
+   zeromem(&md, sizeof(md));
+#endif
+
+   return err;
+}
+
 /**
   Start the PRNG
   @param prng     [out] The PRNG state to initialize
@@ -348,11 +388,10 @@ _LTC_PRNG_EXPORT(fortuna)
 */
 int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
 {
-   int err, x;
-   unsigned long len;
+   int           err;
 
-   LTC_ARGCHK(in   != NULL);
-   LTC_ARGCHK(prng != NULL);
+   LTC_ARGCHK(in    != NULL);
+   LTC_ARGCHK(prng  != NULL);
 
    if (inlen < (unsigned long)fortuna_desc.export_size) {
       return CRYPT_INVALID_ARG;
@@ -361,16 +400,12 @@ int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prn
    if ((err = fortuna_start(prng)) != CRYPT_OK) {
       return err;
    }
-   x = 0;
-   while (inlen > 0) {
-      len = MIN(inlen, 32);
-      if ((err = fortuna_add_entropy(in+x*32, len, prng)) != CRYPT_OK) {
-         return err;
-      }
-      x++;
-      inlen -= len;
+
+   if ((err = _fortuna_update_seed(in, inlen, prng)) != CRYPT_OK) {
+      return err;
    }
-   return CRYPT_OK;
+
+   return err;
 }
 
 /**