From 31393fd9067a1444fe4b73bfac51ab44d8d344e2 Mon Sep 17 00:00:00 2001 From: "Dr. Matthias St. Pierre" Date: Thu, 15 Mar 2018 19:48:43 +0100 Subject: [PATCH] RAND_DRBG: add a function for setting the default DRBG type and flags This commit adds a new api RAND_DRBG_set_defaults() which sets the default type and flags for new DRBG instances. See also #5576. Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/5632) --- crypto/err/openssl.txt | 2 ++ crypto/rand/drbg_ctr.c | 2 +- crypto/rand/drbg_lib.c | 55 +++++++++++++++++++++++++++++++++---- crypto/rand/rand_err.c | 4 +++ crypto/rand/rand_lcl.h | 2 +- include/openssl/rand_drbg.h | 11 ++++++-- include/openssl/randerr.h | 2 ++ ssl/ssl_lib.c | 2 +- util/libcrypto.num | 1 + 9 files changed, 69 insertions(+), 12 deletions(-) diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 176a82b156..728013ba84 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -916,6 +916,7 @@ RAND_F_RAND_DRBG_NEW:109:RAND_DRBG_new RAND_F_RAND_DRBG_RESEED:110:RAND_DRBG_reseed RAND_F_RAND_DRBG_RESTART:102:rand_drbg_restart RAND_F_RAND_DRBG_SET:104:RAND_DRBG_set +RAND_F_RAND_DRBG_SET_DEFAULTS:121:RAND_DRBG_set_defaults RAND_F_RAND_DRBG_UNINSTANTIATE:118:RAND_DRBG_uninstantiate RAND_F_RAND_LOAD_FILE:111:RAND_load_file RAND_F_RAND_POOL_ADD:103:rand_pool_add @@ -2314,6 +2315,7 @@ RAND_R_RANDOM_POOL_OVERFLOW:125:random pool overflow RAND_R_REQUEST_TOO_LARGE_FOR_DRBG:117:request too large for drbg RAND_R_RESEED_ERROR:118:reseed error RAND_R_SELFTEST_FAILURE:119:selftest failure +RAND_R_UNSUPPORTED_DRBG_FLAGS:132:unsupported drbg flags RAND_R_UNSUPPORTED_DRBG_TYPE:120:unsupported drbg type RSA_R_ALGORITHM_MISMATCH:100:algorithm mismatch RSA_R_BAD_E_VALUE:101:bad e value diff --git a/crypto/rand/drbg_ctr.c b/crypto/rand/drbg_ctr.c index 84425dc4e0..ac4af331d7 100644 --- a/crypto/rand/drbg_ctr.c +++ b/crypto/rand/drbg_ctr.c @@ -317,7 +317,7 @@ int drbg_ctr_init(RAND_DRBG *drbg) RAND_DRBG_CTR *ctr = &drbg->data.ctr; size_t keylen; - switch (drbg->nid) { + switch (drbg->type) { default: /* This can't happen, but silence the compiler warning. */ return 0; diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c index 93092c86a9..360e77565c 100644 --- a/crypto/rand/drbg_lib.c +++ b/crypto/rand/drbg_lib.c @@ -113,6 +113,11 @@ static const char ossl_pers_string[] = "OpenSSL NIST SP 800-90A DRBG"; static CRYPTO_ONCE rand_drbg_init = CRYPTO_ONCE_STATIC_INIT; + + +static int rand_drbg_type = RAND_DRBG_TYPE; +static unsigned int rand_drbg_flags = RAND_DRBG_FLAGS; + static unsigned int master_reseed_interval = MASTER_RESEED_INTERVAL; static unsigned int slave_reseed_interval = SLAVE_RESEED_INTERVAL; @@ -127,19 +132,26 @@ static RAND_DRBG *rand_drbg_new(int secure, RAND_DRBG *parent); /* - * Set/initialize |drbg| to be of type |nid|, with optional |flags|. + * Set/initialize |drbg| to be of type |type|, with optional |flags|. + * + * If |type| and |flags| are zero, use the defaults * * Returns 1 on success, 0 on failure. */ -int RAND_DRBG_set(RAND_DRBG *drbg, int nid, unsigned int flags) +int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags) { int ret = 1; + if (type == 0 && flags == 0) { + type = rand_drbg_type; + flags = rand_drbg_flags; + } + drbg->state = DRBG_UNINITIALISED; drbg->flags = flags; - drbg->nid = nid; + drbg->type = type; - switch (nid) { + switch (type) { default: RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_UNSUPPORTED_DRBG_TYPE); return 0; @@ -158,6 +170,37 @@ int RAND_DRBG_set(RAND_DRBG *drbg, int nid, unsigned int flags) return ret; } +/* + * Set/initialize default |type| and |flag| for new drbg instances. + * + * Returns 1 on success, 0 on failure. + */ +int RAND_DRBG_set_defaults(int type, unsigned int flags) +{ + int ret = 1; + + switch (type) { + default: + RANDerr(RAND_F_RAND_DRBG_SET_DEFAULTS, RAND_R_UNSUPPORTED_DRBG_TYPE); + return 0; + case NID_aes_128_ctr: + case NID_aes_192_ctr: + case NID_aes_256_ctr: + break; + } + + if ((flags & ~RAND_DRBG_USED_FLAGS) != 0) { + RANDerr(RAND_F_RAND_DRBG_SET_DEFAULTS, RAND_R_UNSUPPORTED_DRBG_FLAGS); + return 0; + } + + rand_drbg_type = type; + rand_drbg_flags = flags; + + return ret; +} + + /* * Allocate memory and initialize a new DRBG. The DRBG is allocated on * the secure heap if |secure| is nonzero and the secure heap is enabled. @@ -357,7 +400,7 @@ int RAND_DRBG_uninstantiate(RAND_DRBG *drbg) * initial values. */ drbg->meth->uninstantiate(drbg); - return RAND_DRBG_set(drbg, drbg->nid, drbg->flags); + return RAND_DRBG_set(drbg, drbg->type, drbg->flags); } /* @@ -849,7 +892,7 @@ static RAND_DRBG *drbg_setup(RAND_DRBG *parent) { RAND_DRBG *drbg; - drbg = RAND_DRBG_secure_new(RAND_DRBG_NID, 0, parent); + drbg = RAND_DRBG_secure_new(rand_drbg_type, rand_drbg_flags, parent); if (drbg == NULL) return NULL; diff --git a/crypto/rand/rand_err.c b/crypto/rand/rand_err.c index 542499f1a7..36d484c726 100644 --- a/crypto/rand/rand_err.c +++ b/crypto/rand/rand_err.c @@ -31,6 +31,8 @@ static const ERR_STRING_DATA RAND_str_functs[] = { {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_RESEED, 0), "RAND_DRBG_reseed"}, {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_RESTART, 0), "rand_drbg_restart"}, {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_SET, 0), "RAND_DRBG_set"}, + {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_SET_DEFAULTS, 0), + "RAND_DRBG_set_defaults"}, {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_UNINSTANTIATE, 0), "RAND_DRBG_uninstantiate"}, {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_LOAD_FILE, 0), "RAND_load_file"}, @@ -99,6 +101,8 @@ static const ERR_STRING_DATA RAND_str_reasons[] = { "request too large for drbg"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_RESEED_ERROR), "reseed error"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_SELFTEST_FAILURE), "selftest failure"}, + {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNSUPPORTED_DRBG_FLAGS), + "unsupported drbg flags"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNSUPPORTED_DRBG_TYPE), "unsupported drbg type"}, {0, NULL} diff --git a/crypto/rand/rand_lcl.h b/crypto/rand/rand_lcl.h index 2f1a52bb59..32526fbb54 100644 --- a/crypto/rand/rand_lcl.h +++ b/crypto/rand/rand_lcl.h @@ -116,7 +116,7 @@ struct rand_drbg_st { CRYPTO_RWLOCK *lock; RAND_DRBG *parent; int secure; /* 1: allocated on the secure heap, 0: otherwise */ - int nid; /* the underlying algorithm */ + int type; /* the nid of the underlying algorithm */ int fork_count; unsigned short flags; /* various external flags */ diff --git a/include/openssl/rand_drbg.h b/include/openssl/rand_drbg.h index 667a8ab2fd..17ca979da2 100644 --- a/include/openssl/rand_drbg.h +++ b/include/openssl/rand_drbg.h @@ -17,6 +17,11 @@ /* In CTR mode, disable derivation function ctr_df */ # define RAND_DRBG_FLAG_CTR_NO_DF 0x1 +/* A logical OR of all used flag bits (currently there is only one) */ +# define RAND_DRBG_USED_FLAGS ( \ + RAND_DRBG_FLAG_CTR_NO_DF \ + ) + /* * Default security strength (in the sense of [NIST SP 800-90Ar1]) * @@ -30,11 +35,10 @@ * * Currently supported ciphers are: NID_aes_128_ctr, NID_aes_192_ctr and * NID_aes_256_ctr - * - * TODO(DRBG): would be nice to have the NID and strength configurable */ # define RAND_DRBG_STRENGTH 256 -# define RAND_DRBG_NID NID_aes_256_ctr +# define RAND_DRBG_TYPE NID_aes_256_ctr +# define RAND_DRBG_FLAGS 0 # ifdef __cplusplus @@ -47,6 +51,7 @@ extern "C" { RAND_DRBG *RAND_DRBG_new(int type, unsigned int flags, RAND_DRBG *parent); RAND_DRBG *RAND_DRBG_secure_new(int type, unsigned int flags, RAND_DRBG *parent); int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags); +int RAND_DRBG_set_defaults(int type, unsigned int flags); int RAND_DRBG_instantiate(RAND_DRBG *drbg, const unsigned char *pers, size_t perslen); int RAND_DRBG_uninstantiate(RAND_DRBG *drbg); diff --git a/include/openssl/randerr.h b/include/openssl/randerr.h index 81bda4ba51..afc8213927 100644 --- a/include/openssl/randerr.h +++ b/include/openssl/randerr.h @@ -32,6 +32,7 @@ int ERR_load_RAND_strings(void); # define RAND_F_RAND_DRBG_RESEED 110 # define RAND_F_RAND_DRBG_RESTART 102 # define RAND_F_RAND_DRBG_SET 104 +# define RAND_F_RAND_DRBG_SET_DEFAULTS 121 # define RAND_F_RAND_DRBG_UNINSTANTIATE 118 # define RAND_F_RAND_LOAD_FILE 111 # define RAND_F_RAND_POOL_ADD 103 @@ -75,6 +76,7 @@ int ERR_load_RAND_strings(void); # define RAND_R_REQUEST_TOO_LARGE_FOR_DRBG 117 # define RAND_R_RESEED_ERROR 118 # define RAND_R_SELFTEST_FAILURE 119 +# define RAND_R_UNSUPPORTED_DRBG_FLAGS 132 # define RAND_R_UNSUPPORTED_DRBG_TYPE 120 #endif diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 298588cd3d..cd972ae63f 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -696,7 +696,7 @@ SSL *SSL_new(SSL_CTX *ctx) */ if (RAND_get_rand_method() == RAND_OpenSSL()) { s->drbg = - RAND_DRBG_new(RAND_DRBG_NID, 0, RAND_DRBG_get0_public()); + RAND_DRBG_new(0, 0, RAND_DRBG_get0_public()); if (s->drbg == NULL || RAND_DRBG_instantiate(s->drbg, (const unsigned char *) SSL_version_str, diff --git a/util/libcrypto.num b/util/libcrypto.num index 38c902c9c0..16d19526bb 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -4513,3 +4513,4 @@ EVP_PKEY_new_raw_public_key 4454 1_1_1 EXIST::FUNCTION: EVP_PKEY_new_CMAC_key 4455 1_1_1 EXIST::FUNCTION: EVP_PKEY_asn1_set_set_priv_key 4456 1_1_1 EXIST::FUNCTION: EVP_PKEY_asn1_set_set_pub_key 4457 1_1_1 EXIST::FUNCTION: +RAND_DRBG_set_defaults 4458 1_1_1 EXIST::FUNCTION: -- 2.25.1