The branch master has been updated
       via  311276ffe32ab0b161c364727cf8676591dbf47c (commit)
       via  eb238134e0a0fb5ac5c8239ade1dfe77a815aba5 (commit)
      from  a080c3e816e923680e57e647b5cbc3896e8e8106 (commit)


- Log -----------------------------------------------------------------
commit 311276ffe32ab0b161c364727cf8676591dbf47c
Author: Kurt Roeckx <k...@roeckx.be>
Date:   Sun Feb 18 20:55:28 2018 +0100

    Return error when trying to use prediction resistance
    
    There is a requirements of having access to a live entropy source
    which we can't do with the default callbacks. If you need prediction
    resistance you need to set up your own callbacks that follow the
    requirements of NIST SP 800-90C.
    
    Reviewed-by: Dr. Matthias St. Pierre <matthias.st.pie...@ncp-e.com>
    GH: #5402

commit eb238134e0a0fb5ac5c8239ade1dfe77a815aba5
Author: Kurt Roeckx <k...@roeckx.be>
Date:   Sun Feb 18 19:26:55 2018 +0100

    Propagate the request for prediction resistance to the get entropy call
    
    Reviewed-by: Dr. Matthias St. Pierre <matthias.st.pie...@ncp-e.com>
    GH: #5402

-----------------------------------------------------------------------

Summary of changes:
 crypto/err/openssl.txt             |  2 ++
 crypto/include/internal/rand_int.h |  3 ++-
 crypto/rand/drbg_lib.c             | 14 +++++++++-----
 crypto/rand/rand_err.c             |  2 ++
 crypto/rand/rand_lib.c             | 18 +++++++++++++++---
 include/openssl/rand_drbg.h        |  6 ++++--
 include/openssl/randerr.h          |  1 +
 test/drbgtest.c                    | 20 +++++++++++---------
 8 files changed, 46 insertions(+), 20 deletions(-)

diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 728013b..0052ddf 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -2310,6 +2310,8 @@ RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED:128:no drbg 
implementation selected
 RAND_R_PARENT_LOCKING_NOT_ENABLED:130:parent locking not enabled
 RAND_R_PARENT_STRENGTH_TOO_WEAK:131:parent strength too weak
 RAND_R_PERSONALISATION_STRING_TOO_LONG:116:personalisation string too long
+RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED:133:\
+       prediction resistance not supported
 RAND_R_PRNG_NOT_SEEDED:100:PRNG not seeded
 RAND_R_RANDOM_POOL_OVERFLOW:125:random pool overflow
 RAND_R_REQUEST_TOO_LARGE_FOR_DRBG:117:request too large for drbg
diff --git a/crypto/include/internal/rand_int.h 
b/crypto/include/internal/rand_int.h
index d90d9c5..27ca703 100644
--- a/crypto/include/internal/rand_int.h
+++ b/crypto/include/internal/rand_int.h
@@ -34,7 +34,8 @@ size_t rand_acquire_entropy_from_cpu(RAND_POOL *pool);
 /* DRBG entropy callbacks. */
 size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
                              unsigned char **pout,
-                             int entropy, size_t min_len, size_t max_len);
+                             int entropy, size_t min_len, size_t max_len,
+                             int prediction_resistance);
 void rand_drbg_cleanup_entropy(RAND_DRBG *drbg,
                                unsigned char *out, size_t outlen);
 size_t rand_drbg_get_additional_data(unsigned char **pout, size_t max_len);
diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c
index 02ad071..360ea7c 100644
--- a/crypto/rand/drbg_lib.c
+++ b/crypto/rand/drbg_lib.c
@@ -327,7 +327,8 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
     drbg->state = DRBG_ERROR;
     if (drbg->get_entropy != NULL)
         entropylen = drbg->get_entropy(drbg, &entropy, drbg->strength,
-                                   drbg->min_entropylen, drbg->max_entropylen);
+                                       drbg->min_entropylen,
+                                       drbg->max_entropylen, 0);
     if (entropylen < drbg->min_entropylen
         || entropylen > drbg->max_entropylen) {
         RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_ERROR_RETRIEVING_ENTROPY);
@@ -411,7 +412,8 @@ int RAND_DRBG_uninstantiate(RAND_DRBG *drbg)
  * Returns 1 on success, 0 on failure.
  */
 int RAND_DRBG_reseed(RAND_DRBG *drbg,
-                     const unsigned char *adin, size_t adinlen)
+                     const unsigned char *adin, size_t adinlen,
+                     int prediction_resistance)
 {
     unsigned char *entropy = NULL;
     size_t entropylen = 0;
@@ -435,7 +437,9 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
     drbg->state = DRBG_ERROR;
     if (drbg->get_entropy != NULL)
         entropylen = drbg->get_entropy(drbg, &entropy, drbg->strength,
-                                   drbg->min_entropylen, drbg->max_entropylen);
+                                       drbg->min_entropylen,
+                                       drbg->max_entropylen,
+                                       prediction_resistance);
     if (entropylen < drbg->min_entropylen
         || entropylen > drbg->max_entropylen) {
         RANDerr(RAND_F_RAND_DRBG_RESEED, RAND_R_ERROR_RETRIEVING_ENTROPY);
@@ -551,7 +555,7 @@ int rand_drbg_restart(RAND_DRBG *drbg,
             drbg->meth->reseed(drbg, adin, adinlen, NULL, 0);
         } else if (reseeded == 0) {
             /* do a full reseeding if it has not been done yet above */
-            RAND_DRBG_reseed(drbg, NULL, 0);
+            RAND_DRBG_reseed(drbg, NULL, 0, 0);
         }
     }
 
@@ -627,7 +631,7 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, 
size_t outlen,
     }
 
     if (reseed_required || prediction_resistance) {
-        if (!RAND_DRBG_reseed(drbg, adin, adinlen)) {
+        if (!RAND_DRBG_reseed(drbg, adin, adinlen, prediction_resistance)) {
             RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_RESEED_ERROR);
             return 0;
         }
diff --git a/crypto/rand/rand_err.c b/crypto/rand/rand_err.c
index 36d484c..0cd34ac 100644
--- a/crypto/rand/rand_err.c
+++ b/crypto/rand/rand_err.c
@@ -94,6 +94,8 @@ static const ERR_STRING_DATA RAND_str_reasons[] = {
     "parent strength too weak"},
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PERSONALISATION_STRING_TOO_LONG),
     "personalisation string too long"},
+    {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED),
+    "prediction resistance not supported"},
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PRNG_NOT_SEEDED), "PRNG not seeded"},
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_RANDOM_POOL_OVERFLOW),
     "random pool overflow"},
diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c
index 76d5767..dfffb84 100644
--- a/crypto/rand/rand_lib.c
+++ b/crypto/rand/rand_lib.c
@@ -171,8 +171,9 @@ size_t rand_acquire_entropy_from_cpu(RAND_POOL *pool)
  * its entropy will be used up first.
  */
 size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
-                        unsigned char **pout,
-                        int entropy, size_t min_len, size_t max_len)
+                             unsigned char **pout,
+                             int entropy, size_t min_len, size_t max_len,
+                             int prediction_resistance)
 {
     size_t ret = 0;
     size_t entropy_available = 0;
@@ -216,7 +217,7 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
             rand_drbg_lock(drbg->parent);
             if (RAND_DRBG_generate(drbg->parent,
                                    buffer, bytes_needed,
-                                   0,
+                                   prediction_resistance,
                                    (unsigned char *)drbg, sizeof(*drbg)) != 0)
                 bytes = bytes_needed;
             rand_drbg_unlock(drbg->parent);
@@ -225,6 +226,17 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
         }
 
     } else {
+        if (prediction_resistance) {
+            /*
+             * We don't have any entropy sources that comply with the NIST
+             * standard to provide prediction resistance (see NIST SP 800-90C,
+             * Section 5.4).
+             */
+            RANDerr(RAND_F_RAND_DRBG_GET_ENTROPY,
+                    RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED);
+            return 0;
+        }
+
         /* Get entropy by polling system entropy sources. */
         entropy_available = rand_pool_acquire_entropy(pool);
     }
diff --git a/include/openssl/rand_drbg.h b/include/openssl/rand_drbg.h
index 17ca979..790dca5 100644
--- a/include/openssl/rand_drbg.h
+++ b/include/openssl/rand_drbg.h
@@ -61,7 +61,8 @@ void RAND_DRBG_free(RAND_DRBG *drbg);
  * Object "use" functions.
  */
 int RAND_DRBG_reseed(RAND_DRBG *drbg,
-                     const unsigned char *adin, size_t adinlen);
+                     const unsigned char *adin, size_t adinlen,
+                     int prediction_resistance);
 int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
                        int prediction_resistance,
                        const unsigned char *adin, size_t adinlen);
@@ -95,7 +96,8 @@ void *RAND_DRBG_get_ex_data(const RAND_DRBG *dctx, int idx);
 typedef size_t (*RAND_DRBG_get_entropy_fn)(RAND_DRBG *ctx,
                                            unsigned char **pout,
                                            int entropy, size_t min_len,
-                                           size_t max_len);
+                                           size_t max_len,
+                                           int prediction_resistance);
 typedef void (*RAND_DRBG_cleanup_entropy_fn)(RAND_DRBG *ctx,
                                              unsigned char *out, size_t 
outlen);
 typedef size_t (*RAND_DRBG_get_nonce_fn)(RAND_DRBG *ctx, unsigned char **pout,
diff --git a/include/openssl/randerr.h b/include/openssl/randerr.h
index afc8213..4746ad6 100644
--- a/include/openssl/randerr.h
+++ b/include/openssl/randerr.h
@@ -71,6 +71,7 @@ int ERR_load_RAND_strings(void);
 # define RAND_R_PARENT_LOCKING_NOT_ENABLED                130
 # define RAND_R_PARENT_STRENGTH_TOO_WEAK                  131
 # define RAND_R_PERSONALISATION_STRING_TOO_LONG           116
+# define RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED       133
 # define RAND_R_PRNG_NOT_SEEDED                           100
 # define RAND_R_RANDOM_POOL_OVERFLOW                      125
 # define RAND_R_REQUEST_TOO_LARGE_FOR_DRBG                117
diff --git a/test/drbgtest.c b/test/drbgtest.c
index c64628a..4c872f8 100644
--- a/test/drbgtest.c
+++ b/test/drbgtest.c
@@ -118,7 +118,8 @@ typedef struct test_ctx_st {
 } TEST_CTX;
 
 static size_t kat_entropy(RAND_DRBG *drbg, unsigned char **pout,
-                          int entropy, size_t min_len, size_t max_len)
+                          int entropy, size_t min_len, size_t max_len,
+                          int prediction_resistance)
 {
     TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_ex_data(drbg, app_data_index);
 
@@ -182,7 +183,7 @@ static int single_kat(DRBG_SELFTEST_DATA *td)
     /* Reseed DRBG with test entropy and additional input */
     t.entropy = td->entropyreseed;
     t.entropylen = td->entropyreseedlen;
-    if (!TEST_true(RAND_DRBG_reseed(drbg, td->adinreseed, td->adinreseedlen)
+    if (!TEST_true(RAND_DRBG_reseed(drbg, td->adinreseed, td->adinreseedlen, 0)
             || !TEST_true(RAND_DRBG_generate(drbg, buff, td->kat2len, 0,
                                              td->adin2, td->adin2len))
             || !TEST_mem_eq(td->kat2, td->kat2len, buff, td->kat2len)))
@@ -415,12 +416,12 @@ static int error_check(DRBG_SELFTEST_DATA *td)
 
     /* Test explicit reseed with too large additional input */
     if (!init(drbg, td, &t)
-            || RAND_DRBG_reseed(drbg, td->adin, drbg->max_adinlen + 1) > 0)
+            || RAND_DRBG_reseed(drbg, td->adin, drbg->max_adinlen + 1, 0) > 0)
         goto err;
 
     /* Test explicit reseed with entropy source failure */
     t.entropylen = 0;
-    if (!TEST_int_le(RAND_DRBG_reseed(drbg, td->adin, td->adinlen), 0)
+    if (!TEST_int_le(RAND_DRBG_reseed(drbg, td->adin, td->adinlen, 0), 0)
             || !uninstantiate(drbg))
         goto err;
 
@@ -428,7 +429,7 @@ static int error_check(DRBG_SELFTEST_DATA *td)
     if (!init(drbg, td, &t))
         goto err;
     t.entropylen = drbg->max_entropylen + 1;
-    if (!TEST_int_le(RAND_DRBG_reseed(drbg, td->adin, td->adinlen), 0)
+    if (!TEST_int_le(RAND_DRBG_reseed(drbg, td->adin, td->adinlen, 0), 0)
             || !uninstantiate(drbg))
         goto err;
 
@@ -436,7 +437,7 @@ static int error_check(DRBG_SELFTEST_DATA *td)
     if (!init(drbg, td, &t))
         goto err;
     t.entropylen = drbg->min_entropylen - 1;
-    if (!TEST_int_le(RAND_DRBG_reseed(drbg, td->adin, td->adinlen), 0)
+    if (!TEST_int_le(RAND_DRBG_reseed(drbg, td->adin, td->adinlen, 0), 0)
             || !uninstantiate(drbg))
         goto err;
 
@@ -504,7 +505,8 @@ static HOOK_CTX *get_hook_ctx(RAND_DRBG *drbg)
 
 /* Intercepts and counts calls to the get_entropy() callback */
 static size_t get_entropy_hook(RAND_DRBG *drbg, unsigned char **pout,
-                          int entropy, size_t min_len, size_t max_len)
+                              int entropy, size_t min_len, size_t max_len,
+                              int prediction_resistance)
 {
     size_t ret;
     HOOK_CTX *ctx = get_hook_ctx(drbg);
@@ -512,8 +514,8 @@ static size_t get_entropy_hook(RAND_DRBG *drbg, unsigned 
char **pout,
     if (ctx->fail != 0)
         return 0;
 
-    ret = ctx->get_entropy(
-        drbg, pout, entropy, min_len, max_len);
+    ret = ctx->get_entropy(drbg, pout, entropy, min_len, max_len,
+                           prediction_resistance);
 
     if (ret != 0)
         ctx->reseed_count++;
_____
openssl-commits mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-commits

Reply via email to