Squashed commit of the following:
authorPauli <paul.dale@oracle.com>
Tue, 30 Apr 2019 03:43:19 +0000 (13:43 +1000)
committerPauli <paul.dale@oracle.com>
Tue, 30 Apr 2019 03:43:19 +0000 (13:43 +1000)
Digest stored entropy for CRNG test.

Via the FIPS lab, NIST confirmed:

    The CMVP had a chance to discuss this inquiry and we agree that
    hashing the NDRNG block does meet the spirit and letter of AS09.42.

    However, the CMVP did have a few questions: what hash algorithm would
    be used in this application? Is it approved? Is it CAVs tested?

SHA256 is being used here and it will be both approved and CAVs tested.

This means that no raw entropy needs to be kept between RNG seedings, preventing
a potential attack vector aganst the randomness source and the DRBG chains.

It also means the block of secure memory allocated for this purpose is no longer
required.

Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
(Merged from https://github.com/openssl/openssl/pull/8790)

crypto/rand/rand_crng_test.c
crypto/rand/rand_lcl.h
test/drbgtest.c

index 87f4ee1f483aebdc4e3fc8466c68f025e52e60df..1b4f1674b37ae9efbd06d1a35fe23a6f59ccb643 100644 (file)
  */
 
 #include <string.h>
  */
 
 #include <string.h>
+#include <openssl/evp.h>
 #include "internal/rand_int.h"
 #include "internal/thread_once.h"
 #include "rand_lcl.h"
 
 static RAND_POOL *crngt_pool;
 #include "internal/rand_int.h"
 #include "internal/thread_once.h"
 #include "rand_lcl.h"
 
 static RAND_POOL *crngt_pool;
-static unsigned char *crngt_prev;
+static unsigned char crngt_prev[EVP_MAX_MD_SIZE];
 
 
-int (*crngt_get_entropy)(unsigned char *) = &rand_crngt_get_entropy_cb;
+int (*crngt_get_entropy)(unsigned char *, unsigned char *, unsigned int *)
+    = &rand_crngt_get_entropy_cb;
 
 
-int rand_crngt_get_entropy_cb(unsigned char *buf)
+int rand_crngt_get_entropy_cb(unsigned char *buf, unsigned char *md,
+                              unsigned int *md_size)
 {
 {
+    int r;
     size_t n;
     unsigned char *p;
 
     size_t n;
     unsigned char *p;
 
-    while ((n = rand_pool_acquire_entropy(crngt_pool)) != 0)
-        if (n >= CRNGT_BUFSIZ) {
-            p = rand_pool_detach(crngt_pool);
+    n = rand_pool_acquire_entropy(crngt_pool);
+    if (n >= CRNGT_BUFSIZ) {
+        p = rand_pool_detach(crngt_pool);
+        r = EVP_Digest(p, CRNGT_BUFSIZ, md, md_size, EVP_sha256(), NULL);
+        if (r != 0)
             memcpy(buf, p, CRNGT_BUFSIZ);
             memcpy(buf, p, CRNGT_BUFSIZ);
-            rand_pool_reattach(crngt_pool, p);
-            return 1;
-        }
+        rand_pool_reattach(crngt_pool, p);
+        return r;
+    }
     return 0;
     return 0;
-
 }
 }
+
 void rand_crngt_cleanup(void)
 {
     rand_pool_free(crngt_pool);
 void rand_crngt_cleanup(void)
 {
     rand_pool_free(crngt_pool);
-    OPENSSL_secure_free(crngt_prev);
     crngt_pool = NULL;
     crngt_pool = NULL;
-    crngt_prev = NULL;
 }
 
 int rand_crngt_init(void)
 {
 }
 
 int rand_crngt_init(void)
 {
+    unsigned char buf[CRNGT_BUFSIZ];
+
     if ((crngt_pool = rand_pool_new(0, CRNGT_BUFSIZ, CRNGT_BUFSIZ)) == NULL)
         return 0;
     if ((crngt_pool = rand_pool_new(0, CRNGT_BUFSIZ, CRNGT_BUFSIZ)) == NULL)
         return 0;
-    if ((crngt_prev = OPENSSL_secure_malloc(CRNGT_BUFSIZ)) != NULL
-        && crngt_get_entropy(crngt_prev))
+    if (crngt_get_entropy(buf, crngt_prev, NULL)) {
+        OPENSSL_cleanse(buf, sizeof(buf));
         return 1;
         return 1;
+    }
     rand_crngt_cleanup();
     return 0;
 }
     rand_crngt_cleanup();
     return 0;
 }
@@ -74,7 +81,8 @@ size_t rand_crngt_get_entropy(RAND_DRBG *drbg,
                               int entropy, size_t min_len, size_t max_len,
                               int prediction_resistance)
 {
                               int entropy, size_t min_len, size_t max_len,
                               int prediction_resistance)
 {
-    unsigned char buf[CRNGT_BUFSIZ];
+    unsigned char buf[CRNGT_BUFSIZ], md[EVP_MAX_MD_SIZE];
+    unsigned int sz;
     RAND_POOL *pool;
     size_t q, r = 0, s, t = 0;
     int attempts = 3;
     RAND_POOL *pool;
     size_t q, r = 0, s, t = 0;
     int attempts = 3;
@@ -87,17 +95,18 @@ size_t rand_crngt_get_entropy(RAND_DRBG *drbg,
 
     while ((q = rand_pool_bytes_needed(pool, 1)) > 0 && attempts-- > 0) {
         s = q > sizeof(buf) ? sizeof(buf) : q;
 
     while ((q = rand_pool_bytes_needed(pool, 1)) > 0 && attempts-- > 0) {
         s = q > sizeof(buf) ? sizeof(buf) : q;
-        if (!crngt_get_entropy(buf)
-            || memcmp(crngt_prev, buf, CRNGT_BUFSIZ) == 0
+        if (!crngt_get_entropy(buf, md, &sz)
+            || memcmp(crngt_prev, md, sz) == 0
             || !rand_pool_add(pool, buf, s, s * 8))
             goto err;
             || !rand_pool_add(pool, buf, s, s * 8))
             goto err;
-        memcpy(crngt_prev, buf, CRNGT_BUFSIZ);
+        memcpy(crngt_prev, md, sz);
         t += s;
         attempts++;
     }
     r = t;
     *pout = rand_pool_detach(pool);
 err:
         t += s;
         attempts++;
     }
     r = t;
     *pout = rand_pool_detach(pool);
 err:
+    OPENSSL_cleanse(buf, sizeof(buf));
     rand_pool_free(pool);
     return r;
 }
     rand_pool_free(pool);
     return r;
 }
index d793d282139ae18a02bd4d81002801939f2e31ef..3ce5f7ad97c7a723fbb5cd128ac4c66a49b165d7 100644 (file)
@@ -334,8 +334,10 @@ int drbg_hmac_init(RAND_DRBG *drbg);
  * Entropy call back for the FIPS 140-2 section 4.9.2 Conditional Tests.
  * These need to be exposed for the unit tests.
  */
  * Entropy call back for the FIPS 140-2 section 4.9.2 Conditional Tests.
  * These need to be exposed for the unit tests.
  */
-int rand_crngt_get_entropy_cb(unsigned char *buf);
-extern int (*crngt_get_entropy)(unsigned char *);
+int rand_crngt_get_entropy_cb(unsigned char *buf, unsigned char *md,
+                              unsigned int *md_size);
+extern int (*crngt_get_entropy)(unsigned char *buf, unsigned char *md,
+                                unsigned int *md_size);
 int rand_crngt_init(void);
 void rand_crngt_cleanup(void);
 
 int rand_crngt_init(void);
 void rand_crngt_cleanup(void);
 
index bf4c723c779ce11526113e89d07a6df9236231ea..42af048699e30ea2579ee781818477945d29b31f 100644 (file)
@@ -1249,7 +1249,8 @@ static const size_t crngt_num_cases = 6;
 
 static size_t crngt_case, crngt_idx;
 
 
 static size_t crngt_case, crngt_idx;
 
-static int crngt_entropy_cb(unsigned char *buf)
+static int crngt_entropy_cb(unsigned char *buf, unsigned char *md,
+                            unsigned int *md_size)
 {
     size_t i, z;
 
 {
     size_t i, z;
 
@@ -1261,7 +1262,7 @@ static int crngt_entropy_cb(unsigned char *buf)
         z--;
     for (i = 0; i < CRNGT_BUFSIZ; i++)
         buf[i] = (unsigned char)(i + 'A' + z);
         z--;
     for (i = 0; i < CRNGT_BUFSIZ; i++)
         buf[i] = (unsigned char)(i + 'A' + z);
-    return 1;
+    return EVP_Digest(buf, CRNGT_BUFSIZ, md, md_size, EVP_sha256(), NULL);
 }
 
 static int test_crngt(int n)
 }
 
 static int test_crngt(int n)