summaryrefslogtreecommitdiffstats
path: root/crypto/rand/drbg_lib.c
diff options
context:
space:
mode:
authorShane Lontis <shane.lontis@oracle.com>2018-07-24 11:16:38 +1000
committerPauli <paul.dale@oracle.com>2018-09-28 07:22:13 +1000
commit8bf366519661e12fd894dc5420f5b64dccfd7ecd (patch)
tree2dbd982aa266dcc238ac4e973694110974c35b79 /crypto/rand/drbg_lib.c
parent1362190b1b786a87378e55e9a1c20c46b6b6a286 (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.c170
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;