projects
/
openssl.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Add the FIPS related continuous random number generator (CRNG) testing.
[openssl.git]
/
crypto
/
rand
/
drbg_lib.c
diff --git
a/crypto/rand/drbg_lib.c
b/crypto/rand/drbg_lib.c
index ec4aa69db50a3a57690770fbc4596e08f7b182f2..4e1e2ea5e06441ff9f13eafec35376b2cea380a8 100644
(file)
--- a/
crypto/rand/drbg_lib.c
+++ b/
crypto/rand/drbg_lib.c
@@
-1,7
+1,7
@@
/*
* Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved.
*
/*
* Copyright 2011-2018 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the
OpenSSL license
(the "License"). You may not use
+ * Licensed under the
Apache License 2.0
(the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@
-67,7
+67,7
@@
static CRYPTO_THREAD_LOCAL private_drbg;
/* NIST SP 800-90A DRBG recommends the use of a personalization string. */
/* NIST SP 800-90A DRBG recommends the use of a personalization string. */
-static const char ossl_pers_string[] =
"OpenSSL NIST SP 800-90A DRBG"
;
+static const char ossl_pers_string[] =
DRBG_DEFAULT_PERS_STRING
;
static CRYPTO_ONCE rand_drbg_init = CRYPTO_ONCE_STATIC_INIT;
static CRYPTO_ONCE rand_drbg_init = CRYPTO_ONCE_STATIC_INIT;
@@
-158,8
+158,10
@@
int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags)
}
/* If set is called multiple times - clear the old one */
}
/* If set is called multiple times - clear the old one */
- if (
type != drbg->type && drbg->type != 0 && drbg->meth != NULL
) {
+ if (
drbg->type != 0 && (type != drbg->type || flags != drbg->flags)
) {
drbg->meth->uninstantiate(drbg);
drbg->meth->uninstantiate(drbg);
+ rand_pool_free(drbg->adin_pool);
+ drbg->adin_pool = NULL;
}
drbg->state = DRBG_UNINITIALISED;
}
drbg->state = DRBG_UNINITIALISED;
@@
-168,6
+170,7
@@
int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags)
if (type == 0) {
/* Uninitialized; that's okay. */
if (type == 0) {
/* Uninitialized; that's okay. */
+ drbg->meth = NULL;
return 1;
} else if (is_ctr(type)) {
ret = drbg_ctr_init(drbg);
return 1;
} else if (is_ctr(type)) {
ret = drbg_ctr_init(drbg);
@@
-177,12
+180,17
@@
int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags)
else
ret = drbg_hash_init(drbg);
} else {
else
ret = drbg_hash_init(drbg);
} else {
+ drbg->type = 0;
+ drbg->flags = 0;
+ drbg->meth = NULL;
RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_UNSUPPORTED_DRBG_TYPE);
return 0;
}
RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_UNSUPPORTED_DRBG_TYPE);
return 0;
}
- if (ret == 0)
+ if (ret == 0) {
+ drbg->state = DRBG_ERROR;
RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_ERROR_INITIALISING_DRBG);
RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_ERROR_INITIALISING_DRBG);
+ }
return ret;
}
return ret;
}
@@
-233,8
+241,8
@@
static RAND_DRBG *rand_drbg_new(int secure,
unsigned int flags,
RAND_DRBG *parent)
{
unsigned int flags,
RAND_DRBG *parent)
{
- RAND_DRBG *drbg = secure ?
-
OPENSSL_secure_zalloc(sizeof(*drbg))
: OPENSSL_zalloc(sizeof(*drbg));
+ RAND_DRBG *drbg = secure ?
OPENSSL_secure_zalloc(sizeof(*drbg))
+
: OPENSSL_zalloc(sizeof(*drbg));
if (drbg == NULL) {
RANDerr(RAND_F_RAND_DRBG_NEW, ERR_R_MALLOC_FAILURE);
if (drbg == NULL) {
RANDerr(RAND_F_RAND_DRBG_NEW, ERR_R_MALLOC_FAILURE);
@@
-246,8
+254,13
@@
static RAND_DRBG *rand_drbg_new(int secure,
drbg->parent = parent;
if (parent == NULL) {
drbg->parent = parent;
if (parent == NULL) {
+#ifdef FIPS_MODE
+ drbg->get_entropy = rand_crngt_get_entropy;
+ drbg->cleanup_entropy = rand_crngt_cleanup_entropy;
+#else
drbg->get_entropy = rand_drbg_get_entropy;
drbg->cleanup_entropy = rand_drbg_cleanup_entropy;
drbg->get_entropy = rand_drbg_get_entropy;
drbg->cleanup_entropy = rand_drbg_cleanup_entropy;
+#endif
#ifndef RAND_DRBG_GET_RANDOM_NONCE
drbg->get_nonce = rand_drbg_get_nonce;
drbg->cleanup_nonce = rand_drbg_cleanup_nonce;
#ifndef RAND_DRBG_GET_RANDOM_NONCE
drbg->get_nonce = rand_drbg_get_nonce;
drbg->cleanup_nonce = rand_drbg_cleanup_nonce;
@@
-287,10
+300,7
@@
static RAND_DRBG *rand_drbg_new(int secure,
return drbg;
err:
return drbg;
err:
- if (drbg->secure)
- OPENSSL_secure_free(drbg);
- else
- OPENSSL_free(drbg);
+ RAND_DRBG_free(drbg);
return NULL;
}
return NULL;
}
@@
-315,6
+325,7
@@
void RAND_DRBG_free(RAND_DRBG *drbg)
if (drbg->meth != NULL)
drbg->meth->uninstantiate(drbg);
if (drbg->meth != NULL)
drbg->meth->uninstantiate(drbg);
+ rand_pool_free(drbg->adin_pool);
CRYPTO_THREAD_lock_free(drbg->lock);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DRBG, drbg, &drbg->ex_data);
CRYPTO_THREAD_lock_free(drbg->lock);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DRBG, drbg, &drbg->ex_data);
@@
-415,15
+426,6
@@
int RAND_DRBG_instantiate(RAND_DRBG *drbg,
drbg->cleanup_entropy(drbg, entropy, entropylen);
if (nonce != NULL && drbg->cleanup_nonce != NULL)
drbg->cleanup_nonce(drbg, nonce, noncelen);
drbg->cleanup_entropy(drbg, entropy, entropylen);
if (nonce != NULL && drbg->cleanup_nonce != NULL)
drbg->cleanup_nonce(drbg, nonce, noncelen);
- if (drbg->pool != NULL) {
- if (drbg->state == DRBG_READY) {
- RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
- RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED);
- drbg->state = DRBG_ERROR;
- }
- rand_pool_free(drbg->pool);
- drbg->pool = NULL;
- }
if (drbg->state == DRBG_READY)
return 1;
return 0;
if (drbg->state == DRBG_READY)
return 1;
return 0;
@@
-440,6
+442,7
@@
int RAND_DRBG_uninstantiate(RAND_DRBG *drbg)
{
int index = -1, type, flags;
if (drbg->meth == NULL) {
{
int index = -1, type, flags;
if (drbg->meth == NULL) {
+ drbg->state = DRBG_ERROR;
RANDerr(RAND_F_RAND_DRBG_UNINSTANTIATE,
RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED);
return 0;
RANDerr(RAND_F_RAND_DRBG_UNINSTANTIATE,
RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED);
return 0;
@@
-559,11
+562,11
@@
int rand_drbg_restart(RAND_DRBG *drbg,
const unsigned char *adin = NULL;
size_t adinlen = 0;
const unsigned char *adin = NULL;
size_t adinlen = 0;
- if (drbg->pool != NULL) {
+ if (drbg->
seed_
pool != NULL) {
RANDerr(RAND_F_RAND_DRBG_RESTART, ERR_R_INTERNAL_ERROR);
drbg->state = DRBG_ERROR;
RANDerr(RAND_F_RAND_DRBG_RESTART, ERR_R_INTERNAL_ERROR);
drbg->state = DRBG_ERROR;
- rand_pool_free(drbg->pool);
- drbg->pool = NULL;
+ rand_pool_free(drbg->
seed_
pool);
+ drbg->
seed_
pool = NULL;
return 0;
}
return 0;
}
@@
-583,8
+586,8
@@
int rand_drbg_restart(RAND_DRBG *drbg,
}
/* will be picked up by the rand_drbg_get_entropy() callback */
}
/* will be picked up by the rand_drbg_get_entropy() callback */
- drbg->pool = rand_pool_attach(buffer, len, entropy);
- if (drbg->pool == NULL)
+ drbg->
seed_
pool = rand_pool_attach(buffer, len, entropy);
+ if (drbg->
seed_
pool == NULL)
return 0;
} else {
if (drbg->max_adinlen < len) {
return 0;
} else {
if (drbg->max_adinlen < len) {
@@
-630,14
+633,8
@@
int rand_drbg_restart(RAND_DRBG *drbg,
}
}
}
}
- /* check whether a given entropy pool was cleared properly during reseed */
- if (drbg->pool != NULL) {
- drbg->state = DRBG_ERROR;
- RANDerr(RAND_F_RAND_DRBG_RESTART, ERR_R_INTERNAL_ERROR);
- rand_pool_free(drbg->pool);
- drbg->pool = NULL;
- return 0;
- }
+ rand_pool_free(drbg->seed_pool);
+ drbg->seed_pool = NULL;
return drbg->state == DRBG_READY;
}
return drbg->state == DRBG_READY;
}
@@
-737,9
+734,18
@@
int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen)
unsigned char *additional = NULL;
size_t additional_len;
size_t chunk;
unsigned char *additional = NULL;
size_t additional_len;
size_t chunk;
- size_t ret;
+ size_t ret = 0;
+
+ if (drbg->adin_pool == NULL) {
+ if (drbg->type == 0)
+ goto err;
+ drbg->adin_pool = rand_pool_new(0, 0, drbg->max_adinlen);
+ if (drbg->adin_pool == NULL)
+ goto err;
+ }
- additional_len = rand_drbg_get_additional_data(&additional, drbg->max_adinlen);
+ additional_len = rand_drbg_get_additional_data(drbg->adin_pool,
+ &additional);
for ( ; outlen > 0; outlen -= chunk, out += chunk) {
chunk = outlen;
for ( ; outlen > 0; outlen -= chunk, out += chunk) {
chunk = outlen;
@@
-751,9
+757,9
@@
int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen)
}
ret = 1;
}
ret = 1;
-err:
- if (additional
_len != 0
)
-
OPENSSL_secure_clear_free(additional, additional_len
);
+
err:
+ if (additional
!= NULL
)
+
rand_drbg_cleanup_additional_data(drbg->adin_pool, additional
);
return ret;
}
return ret;
}
@@
-1044,12
+1050,8
@@
static int drbg_bytes(unsigned char *out, int count)
* Calculates the minimum length of a full entropy buffer
* which is necessary to seed (i.e. instantiate) the DRBG
* successfully.
* Calculates the minimum length of a full entropy buffer
* which is necessary to seed (i.e. instantiate) the DRBG
* successfully.
- *
- * NOTE: There is a copy of this function in drbgtest.c.
- * If you change anything here, you need to update
- * the copy accordingly.
*/
*/
-s
tatic s
ize_t rand_drbg_seedlen(RAND_DRBG *drbg)
+size_t rand_drbg_seedlen(RAND_DRBG *drbg)
{
/*
* If no os entropy source is available then RAND_seed(buffer, bufsize)
{
/*
* If no os entropy source is available then RAND_seed(buffer, bufsize)
@@
-1086,7
+1088,7
@@
static int drbg_add(const void *buf, int num, double randomness)
int ret = 0;
RAND_DRBG *drbg = RAND_DRBG_get0_master();
size_t buflen;
int ret = 0;
RAND_DRBG *drbg = RAND_DRBG_get0_master();
size_t buflen;
- size_t seedlen
= rand_drbg_seedlen(drbg)
;
+ size_t seedlen;
if (drbg == NULL)
return 0;
if (drbg == NULL)
return 0;
@@
-1094,6
+1096,9
@@
static int drbg_add(const void *buf, int num, double randomness)
if (num < 0 || randomness < 0.0)
return 0;
if (num < 0 || randomness < 0.0)
return 0;
+ rand_drbg_lock(drbg);
+ seedlen = rand_drbg_seedlen(drbg);
+
buflen = (size_t)num;
if (buflen < seedlen || randomness < (double) seedlen) {
buflen = (size_t)num;
if (buflen < seedlen || randomness < (double) seedlen) {
@@
-1103,10
+1108,13
@@
static int drbg_add(const void *buf, int num, double randomness)
* inevitably. So we use a trick to mix the buffer contents into
* the DRBG state without forcing a reseeding: we generate a
* dummy random byte, using the buffer content as additional data.
* inevitably. So we use a trick to mix the buffer contents into
* the DRBG state without forcing a reseeding: we generate a
* dummy random byte, using the buffer content as additional data.
+ * Note: This won't work with RAND_DRBG_FLAG_CTR_NO_DF.
*/
unsigned char dummy[1];
*/
unsigned char dummy[1];
- return RAND_DRBG_generate(drbg, dummy, sizeof(dummy), 0, buf, buflen);
+ ret = RAND_DRBG_generate(drbg, dummy, sizeof(dummy), 0, buf, buflen);
+ rand_drbg_unlock(drbg);
+ return ret;
#else
/*
* If an os entropy source is avaible then we declare the buffer content
#else
/*
* If an os entropy source is avaible then we declare the buffer content
@@
-1130,7
+1138,6
@@
static int drbg_add(const void *buf, int num, double randomness)
randomness = (double)seedlen;
}
randomness = (double)seedlen;
}
- rand_drbg_lock(drbg);
ret = rand_drbg_restart(drbg, buf, buflen, (size_t)(8 * randomness));
rand_drbg_unlock(drbg);
ret = rand_drbg_restart(drbg, buf, buflen, (size_t)(8 * randomness));
rand_drbg_unlock(drbg);