diff options
author | Shane Lontis <shane.lontis@oracle.com> | 2018-07-24 11:16:38 +1000 |
---|---|---|
committer | Pauli <paul.dale@oracle.com> | 2018-09-28 07:22:13 +1000 |
commit | 8bf366519661e12fd894dc5420f5b64dccfd7ecd (patch) | |
tree | 2dbd982aa266dcc238ac4e973694110974c35b79 /crypto/rand/drbg_lib.c | |
parent | 1362190b1b786a87378e55e9a1c20c46b6b6a286 (diff) |
Added DRBG_HMAC & DRBG_HASH + Added defaults for setting DRBG for master/public/private + renamed generate_counter back to reseed_counter + generated new cavs data tests
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/6779)
Diffstat (limited to 'crypto/rand/drbg_lib.c')
-rw-r--r-- | crypto/rand/drbg_lib.c | 170 |
1 files changed, 123 insertions, 47 deletions
diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c index 9c315ed68d..10a17a9a5f 100644 --- a/crypto/rand/drbg_lib.c +++ b/crypto/rand/drbg_lib.c @@ -72,9 +72,24 @@ 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; +#define RAND_DRBG_TYPE_FLAGS ( \ + RAND_DRBG_FLAG_MASTER | RAND_DRBG_FLAG_PUBLIC | RAND_DRBG_FLAG_PRIVATE ) + +#define RAND_DRBG_TYPE_MASTER 0 +#define RAND_DRBG_TYPE_PUBLIC 1 +#define RAND_DRBG_TYPE_PRIVATE 2 + +/* Defaults */ +static int rand_drbg_type[3] = { + RAND_DRBG_TYPE, /* Master */ + RAND_DRBG_TYPE, /* Public */ + RAND_DRBG_TYPE /* Private */ +}; +static unsigned int rand_drbg_flags[3] = { + RAND_DRBG_FLAGS | RAND_DRBG_FLAG_MASTER, /* Master */ + RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PUBLIC, /* Public */ + RAND_DRBG_FLAGS | RAND_DRBG_FLAG_PRIVATE /* Private */ +}; static unsigned int master_reseed_interval = MASTER_RESEED_INTERVAL; static unsigned int slave_reseed_interval = SLAVE_RESEED_INTERVAL; @@ -84,15 +99,48 @@ static time_t slave_reseed_time_interval = SLAVE_RESEED_TIME_INTERVAL; /* A logical OR of all used DRBG flag bits (currently there is only one) */ static const unsigned int rand_drbg_used_flags = - RAND_DRBG_FLAG_CTR_NO_DF; + RAND_DRBG_FLAG_CTR_NO_DF | RAND_DRBG_FLAG_HMAC | RAND_DRBG_TYPE_FLAGS; + -static RAND_DRBG *drbg_setup(RAND_DRBG *parent); +static RAND_DRBG *drbg_setup(RAND_DRBG *parent, int drbg_type); static RAND_DRBG *rand_drbg_new(int secure, int type, unsigned int flags, RAND_DRBG *parent); +static int is_ctr(int type) +{ + switch (type) { + case NID_aes_128_ctr: + case NID_aes_192_ctr: + case NID_aes_256_ctr: + return 1; + default: + return 0; + } +} + +static int is_digest(int type) +{ + switch (type) { + case NID_sha1: + case NID_sha224: + case NID_sha256: + case NID_sha384: + case NID_sha512: + case NID_sha512_224: + case NID_sha512_256: + case NID_sha3_224: + case NID_sha3_256: + case NID_sha3_384: + case NID_sha3_512: + return 1; + default: + return 0; + } +} + /* * Set/initialize |drbg| to be of type |type|, with optional |flags|. * @@ -105,26 +153,32 @@ 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; + type = rand_drbg_type[RAND_DRBG_TYPE_MASTER]; + flags = rand_drbg_flags[RAND_DRBG_TYPE_MASTER]; + } + + /* If set is called multiple times - clear the old one */ + if (type != drbg->type && drbg->type != 0 && drbg->meth != NULL) { + drbg->meth->uninstantiate(drbg); } drbg->state = DRBG_UNINITIALISED; drbg->flags = flags; drbg->type = type; - switch (type) { - default: - RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_UNSUPPORTED_DRBG_TYPE); - return 0; - case 0: + if (type == 0) { /* Uninitialized; that's okay. */ return 1; - case NID_aes_128_ctr: - case NID_aes_192_ctr: - case NID_aes_256_ctr: + } else if (is_ctr(type)) { ret = drbg_ctr_init(drbg); - break; + } else if (is_digest(type)) { + if (flags & RAND_DRBG_FLAG_HMAC) + ret = drbg_hmac_init(drbg); + else + ret = drbg_hash_init(drbg); + } else { + RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_UNSUPPORTED_DRBG_TYPE); + return 0; } if (ret == 0) @@ -139,16 +193,10 @@ int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags) */ int RAND_DRBG_set_defaults(int type, unsigned int flags) { - int ret = 1; - - switch (type) { - default: + int all; + if (!(is_digest(type) || is_ctr(type))) { 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) { @@ -156,10 +204,20 @@ int RAND_DRBG_set_defaults(int type, unsigned int flags) return 0; } - rand_drbg_type = type; - rand_drbg_flags = flags; - - return ret; + all = ((flags & RAND_DRBG_TYPE_FLAGS) == 0); + if (all || (flags & RAND_DRBG_FLAG_MASTER) != 0) { + rand_drbg_type[RAND_DRBG_TYPE_MASTER] = type; + rand_drbg_flags[RAND_DRBG_TYPE_MASTER] = flags | RAND_DRBG_FLAG_MASTER; + } + if (all || (flags & RAND_DRBG_FLAG_PUBLIC) != 0) { + rand_drbg_type[RAND_DRBG_TYPE_PUBLIC] = type; + rand_drbg_flags[RAND_DRBG_TYPE_PUBLIC] = flags | RAND_DRBG_FLAG_PUBLIC; + } + if (all || (flags & RAND_DRBG_FLAG_PRIVATE) != 0) { + rand_drbg_type[RAND_DRBG_TYPE_PRIVATE] = type; + rand_drbg_flags[RAND_DRBG_TYPE_PRIVATE] = flags | RAND_DRBG_FLAG_PRIVATE; + } + return 1; } @@ -341,13 +399,13 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg, } drbg->state = DRBG_READY; - drbg->generate_counter = 0; + drbg->reseed_gen_counter = 1; drbg->reseed_time = time(NULL); - if (drbg->reseed_counter > 0) { + if (drbg->reseed_prop_counter > 0) { if (drbg->parent == NULL) - drbg->reseed_counter++; + drbg->reseed_prop_counter++; else - drbg->reseed_counter = drbg->parent->reseed_counter; + drbg->reseed_prop_counter = drbg->parent->reseed_prop_counter; } end: @@ -378,6 +436,7 @@ end: */ int RAND_DRBG_uninstantiate(RAND_DRBG *drbg) { + int index = -1, type, flags; if (drbg->meth == NULL) { RANDerr(RAND_F_RAND_DRBG_UNINSTANTIATE, RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED); @@ -389,7 +448,23 @@ int RAND_DRBG_uninstantiate(RAND_DRBG *drbg) * initial values. */ drbg->meth->uninstantiate(drbg); - return RAND_DRBG_set(drbg, drbg->type, drbg->flags); + + /* The reset uses the default values for type and flags */ + if (drbg->flags & RAND_DRBG_FLAG_MASTER) + index = RAND_DRBG_TYPE_MASTER; + else if (drbg->flags & RAND_DRBG_FLAG_PRIVATE) + index = RAND_DRBG_TYPE_PRIVATE; + else if (drbg->flags & RAND_DRBG_FLAG_PUBLIC) + index = RAND_DRBG_TYPE_PUBLIC; + + if (index != -1) { + flags = rand_drbg_flags[index]; + type = rand_drbg_type[index]; + } else { + flags = drbg->flags; + type = drbg->type; + } + return RAND_DRBG_set(drbg, type, flags); } /* @@ -438,13 +513,13 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg, goto end; drbg->state = DRBG_READY; - drbg->generate_counter = 0; + drbg->reseed_gen_counter = 1; drbg->reseed_time = time(NULL); - if (drbg->reseed_counter > 0) { + if (drbg->reseed_prop_counter > 0) { if (drbg->parent == NULL) - drbg->reseed_counter++; + drbg->reseed_prop_counter++; else - drbg->reseed_counter = drbg->parent->reseed_counter; + drbg->reseed_prop_counter = drbg->parent->reseed_prop_counter; } end: @@ -604,7 +679,7 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen, } if (drbg->reseed_interval > 0) { - if (drbg->generate_counter >= drbg->reseed_interval) + if (drbg->reseed_gen_counter > drbg->reseed_interval) reseed_required = 1; } if (drbg->reseed_time_interval > 0) { @@ -613,8 +688,8 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen, || now - drbg->reseed_time >= drbg->reseed_time_interval) reseed_required = 1; } - if (drbg->reseed_counter > 0 && drbg->parent != NULL) { - if (drbg->reseed_counter != drbg->parent->reseed_counter) + if (drbg->reseed_prop_counter > 0 && drbg->parent != NULL) { + if (drbg->reseed_prop_counter != drbg->parent->reseed_prop_counter) reseed_required = 1; } @@ -633,7 +708,7 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen, return 0; } - drbg->generate_counter++; + drbg->reseed_gen_counter++; return 1; } @@ -850,11 +925,12 @@ void *RAND_DRBG_get_ex_data(const RAND_DRBG *drbg, int idx) * * Returns a pointer to the new DRBG instance on success, NULL on failure. */ -static RAND_DRBG *drbg_setup(RAND_DRBG *parent) +static RAND_DRBG *drbg_setup(RAND_DRBG *parent, int drbg_type) { RAND_DRBG *drbg; - drbg = RAND_DRBG_secure_new(rand_drbg_type, rand_drbg_flags, parent); + drbg = RAND_DRBG_secure_new(rand_drbg_type[drbg_type], + rand_drbg_flags[drbg_type], parent); if (drbg == NULL) return NULL; @@ -863,7 +939,7 @@ static RAND_DRBG *drbg_setup(RAND_DRBG *parent) goto err; /* enable seed propagation */ - drbg->reseed_counter = 1; + drbg->reseed_prop_counter = 1; /* * Ignore instantiation error to support just-in-time instantiation. @@ -900,7 +976,7 @@ DEFINE_RUN_ONCE_STATIC(do_rand_drbg_init) if (!CRYPTO_THREAD_init_local(&public_drbg, NULL)) goto err1; - master_drbg = drbg_setup(NULL); + master_drbg = drbg_setup(NULL, RAND_DRBG_TYPE_MASTER); if (master_drbg == NULL) goto err2; @@ -1032,7 +1108,7 @@ RAND_DRBG *RAND_DRBG_get0_public(void) if (drbg == NULL) { if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_RAND)) return NULL; - drbg = drbg_setup(master_drbg); + drbg = drbg_setup(master_drbg, RAND_DRBG_TYPE_PUBLIC); CRYPTO_THREAD_set_local(&public_drbg, drbg); } return drbg; @@ -1053,7 +1129,7 @@ RAND_DRBG *RAND_DRBG_get0_private(void) if (drbg == NULL) { if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_RAND)) return NULL; - drbg = drbg_setup(master_drbg); + drbg = drbg_setup(master_drbg, RAND_DRBG_TYPE_PRIVATE); CRYPTO_THREAD_set_local(&private_drbg, drbg); } return drbg; |