From 35503b7cdc38b21739df1163d6d24b00dd386bef Mon Sep 17 00:00:00 2001 From: Kurt Roeckx Date: Sun, 4 Mar 2018 13:23:05 +0100 Subject: [PATCH] Check the parent DRBG's strength We currently don't support the algorithm from NIST SP 800-90C 10.1.2 to use a weaker DRBG as source Reviewed-by: Dr. Matthias St. Pierre GH: #5506 --- crypto/err/openssl.txt | 2 ++ crypto/rand/drbg_lib.c | 9 +++++++++ crypto/rand/rand_err.c | 4 ++++ crypto/rand/rand_lib.c | 12 +++++++++++- include/openssl/randerr.h | 2 ++ 5 files changed, 28 insertions(+), 1 deletion(-) diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 9a41ea8e92..3f1c735417 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -907,6 +907,7 @@ RAND_F_GET_ENTROPY:106:get_entropy RAND_F_RAND_BYTES:100:RAND_bytes RAND_F_RAND_DRBG_ENABLE_LOCKING:119:rand_drbg_enable_locking RAND_F_RAND_DRBG_GENERATE:107:RAND_DRBG_generate +RAND_F_RAND_DRBG_GET_ENTROPY:120:rand_drbg_get_entropy RAND_F_RAND_DRBG_INSTANTIATE:108:RAND_DRBG_instantiate RAND_F_RAND_DRBG_NEW:109:RAND_DRBG_new RAND_F_RAND_DRBG_RESEED:110:RAND_DRBG_reseed @@ -2300,6 +2301,7 @@ RAND_R_NOT_A_REGULAR_FILE:122:Not a regular file RAND_R_NOT_INSTANTIATED:115:not instantiated 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_PRNG_NOT_SEEDED:100:PRNG not seeded RAND_R_RANDOM_POOL_OVERFLOW:125:random pool overflow diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c index c43f571d64..daac770d36 100644 --- a/crypto/rand/drbg_lib.c +++ b/crypto/rand/drbg_lib.c @@ -178,6 +178,15 @@ static RAND_DRBG *rand_drbg_new(int secure, if (RAND_DRBG_set(drbg, type, flags) == 0) goto err; + if (parent != NULL && drbg->strength > parent->strength) { + /* + * We currently don't support the algorithm from NIST SP 800-90C + * 10.1.2 to use a weaker DRBG as source + */ + RANDerr(RAND_F_RAND_DRBG_NEW, RAND_R_PARENT_STRENGTH_TOO_WEAK); + goto err; + } + if (!RAND_DRBG_set_callbacks(drbg, rand_drbg_get_entropy, rand_drbg_cleanup_entropy, NULL, NULL)) diff --git a/crypto/rand/rand_err.c b/crypto/rand/rand_err.c index e92c33f4da..22467d83a1 100644 --- a/crypto/rand/rand_err.c +++ b/crypto/rand/rand_err.c @@ -23,6 +23,8 @@ static const ERR_STRING_DATA RAND_str_functs[] = { "rand_drbg_enable_locking"}, {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_GENERATE, 0), "RAND_DRBG_generate"}, + {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_GET_ENTROPY, 0), + "rand_drbg_get_entropy"}, {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_INSTANTIATE, 0), "RAND_DRBG_instantiate"}, {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_NEW, 0), "RAND_DRBG_new"}, @@ -86,6 +88,8 @@ static const ERR_STRING_DATA RAND_str_reasons[] = { "no drbg implementation selected"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PARENT_LOCKING_NOT_ENABLED), "parent locking not enabled"}, + {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PARENT_STRENGTH_TOO_WEAK), + "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_PRNG_NOT_SEEDED), "PRNG not seeded"}, diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c index b8b7b6e8c9..d328935637 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -176,8 +176,18 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg, { size_t ret = 0; size_t entropy_available = 0; - RAND_POOL *pool = RAND_POOL_new(entropy, min_len, max_len); + RAND_POOL *pool; + + if (drbg->parent && drbg->strength > drbg->parent->strength) { + /* + * We currently don't support the algorithm from NIST SP 800-90C + * 10.1.2 to use a weaker DRBG as source + */ + RANDerr(RAND_F_RAND_DRBG_GET_ENTROPY, RAND_R_PARENT_STRENGTH_TOO_WEAK); + return 0; + } + pool = RAND_POOL_new(entropy, min_len, max_len); if (pool == NULL) return 0; diff --git a/include/openssl/randerr.h b/include/openssl/randerr.h index 4cfc06d9c4..81bda4ba51 100644 --- a/include/openssl/randerr.h +++ b/include/openssl/randerr.h @@ -26,6 +26,7 @@ int ERR_load_RAND_strings(void); # define RAND_F_RAND_BYTES 100 # define RAND_F_RAND_DRBG_ENABLE_LOCKING 119 # define RAND_F_RAND_DRBG_GENERATE 107 +# define RAND_F_RAND_DRBG_GET_ENTROPY 120 # define RAND_F_RAND_DRBG_INSTANTIATE 108 # define RAND_F_RAND_DRBG_NEW 109 # define RAND_F_RAND_DRBG_RESEED 110 @@ -67,6 +68,7 @@ int ERR_load_RAND_strings(void); # define RAND_R_NOT_INSTANTIATED 115 # define RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED 128 # 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_PRNG_NOT_SEEDED 100 # define RAND_R_RANDOM_POOL_OVERFLOW 125 -- 2.25.1