Make the RAND code available from inside the FIPS module
Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com> (Merged from https://github.com/openssl/openssl/pull/9035)
This commit is contained in:
parent
0da1d43a94
commit
57ca171a13
13 changed files with 105 additions and 43 deletions
|
@ -1,3 +1,6 @@
|
|||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=\
|
||||
hmac.c hm_ameth.c hm_meth.c
|
||||
|
||||
$COMMON=hmac.c hm_meth.c
|
||||
|
||||
SOURCE[../../libcrypto]=$COMMON hm_ameth.c
|
||||
SOURCE[../../providers/fips]=$COMMON
|
||||
|
|
|
@ -152,6 +152,15 @@ static int hmac_ctrl_str(EVP_MAC_IMPL *hctx, const char *type,
|
|||
{
|
||||
if (!value)
|
||||
return 0;
|
||||
#ifndef FIPS_MODE
|
||||
/*
|
||||
* We don't have EVP_get_digestbyname() in FIPS_MODE. That function returns
|
||||
* an EVP_MD without an associated provider implementation (i.e. it is
|
||||
* using "implicit fetch"). We could replace it with an "explicit" fetch
|
||||
* using EVP_MD_fetch(), but we'd then be required to free the returned
|
||||
* EVP_MD somewhere. Probably the complexity isn't worth it as we are
|
||||
* unlikely to need this ctrl in FIPS_MODE anyway.
|
||||
*/
|
||||
if (strcmp(type, "digest") == 0) {
|
||||
const EVP_MD *d = EVP_get_digestbyname(value);
|
||||
|
||||
|
@ -159,6 +168,7 @@ static int hmac_ctrl_str(EVP_MAC_IMPL *hctx, const char *type,
|
|||
return 0;
|
||||
return hmac_ctrl_int(hctx, EVP_MAC_CTRL_SET_MD, d);
|
||||
}
|
||||
#endif
|
||||
if (strcmp(type, "key") == 0)
|
||||
return EVP_str2ctrl(hmac_ctrl_str_cb, hctx, EVP_MAC_CTRL_SET_KEY,
|
||||
value);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=\
|
||||
randfile.c rand_lib.c rand_err.c rand_crng_test.c rand_egd.c \
|
||||
rand_win.c rand_unix.c rand_vms.c drbg_lib.c drbg_ctr.c rand_vxworks.c \
|
||||
drbg_hash.c drbg_hmac.c
|
||||
|
||||
$COMMON=rand_lib.c rand_crng_test.c rand_win.c rand_unix.c rand_vms.c \
|
||||
drbg_lib.c drbg_ctr.c rand_vxworks.c drbg_hash.c drbg_hmac.c
|
||||
|
||||
SOURCE[../../libcrypto]=$COMMON randfile.c rand_err.c rand_egd.c
|
||||
SOURCE[../../providers/fips]=$COMMON
|
||||
|
|
|
@ -354,6 +354,7 @@ static int drbg_ctr_uninstantiate(RAND_DRBG *drbg)
|
|||
{
|
||||
EVP_CIPHER_CTX_free(drbg->data.ctr.ctx);
|
||||
EVP_CIPHER_CTX_free(drbg->data.ctr.ctx_df);
|
||||
EVP_CIPHER_meth_free(drbg->data.ctr.cipher);
|
||||
OPENSSL_cleanse(&drbg->data.ctr, sizeof(drbg->data.ctr));
|
||||
return 1;
|
||||
}
|
||||
|
@ -369,6 +370,7 @@ int drbg_ctr_init(RAND_DRBG *drbg)
|
|||
{
|
||||
RAND_DRBG_CTR *ctr = &drbg->data.ctr;
|
||||
size_t keylen;
|
||||
EVP_CIPHER *cipher = NULL;
|
||||
|
||||
switch (drbg->type) {
|
||||
default:
|
||||
|
@ -376,17 +378,22 @@ int drbg_ctr_init(RAND_DRBG *drbg)
|
|||
return 0;
|
||||
case NID_aes_128_ctr:
|
||||
keylen = 16;
|
||||
ctr->cipher = EVP_aes_128_ecb();
|
||||
cipher = EVP_CIPHER_fetch(drbg->libctx, "AES-128-ECB", "");
|
||||
break;
|
||||
case NID_aes_192_ctr:
|
||||
keylen = 24;
|
||||
ctr->cipher = EVP_aes_192_ecb();
|
||||
cipher = EVP_CIPHER_fetch(drbg->libctx, "AES-192-ECB", "");
|
||||
break;
|
||||
case NID_aes_256_ctr:
|
||||
keylen = 32;
|
||||
ctr->cipher = EVP_aes_256_ecb();
|
||||
cipher = EVP_CIPHER_fetch(drbg->libctx, "AES-256-ECB", "");
|
||||
break;
|
||||
}
|
||||
if (cipher == NULL)
|
||||
return 0;
|
||||
|
||||
EVP_CIPHER_meth_free(ctr->cipher);
|
||||
ctr->cipher = cipher;
|
||||
|
||||
drbg->meth = &drbg_ctr_meth;
|
||||
|
||||
|
|
|
@ -289,6 +289,7 @@ static int drbg_hash_generate(RAND_DRBG *drbg,
|
|||
|
||||
static int drbg_hash_uninstantiate(RAND_DRBG *drbg)
|
||||
{
|
||||
EVP_MD_meth_free(drbg->data.hash.md);
|
||||
EVP_MD_CTX_free(drbg->data.hash.ctx);
|
||||
OPENSSL_cleanse(&drbg->data.hash, sizeof(drbg->data.hash));
|
||||
return 1;
|
||||
|
@ -303,23 +304,39 @@ static RAND_DRBG_METHOD drbg_hash_meth = {
|
|||
|
||||
int drbg_hash_init(RAND_DRBG *drbg)
|
||||
{
|
||||
const EVP_MD *md;
|
||||
EVP_MD *md;
|
||||
RAND_DRBG_HASH *hash = &drbg->data.hash;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
/* Any approved digest is allowed */
|
||||
md = EVP_get_digestbynid(drbg->type);
|
||||
md = EVP_MD_meth_dup(EVP_get_digestbynid(drbg->type));
|
||||
#else
|
||||
/* TODO(3.0): Fill this out with the complete list of allowed digests */
|
||||
switch (drbg->type) {
|
||||
default:
|
||||
return 0;
|
||||
case NID_sha256:
|
||||
md = EVP_MD_fetch(drbg->libctx, "SHA256", "");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (md == NULL)
|
||||
return 0;
|
||||
|
||||
|
||||
drbg->meth = &drbg_hash_meth;
|
||||
hash->md = md;
|
||||
|
||||
if (hash->ctx == NULL) {
|
||||
hash->ctx = EVP_MD_CTX_new();
|
||||
if (hash->ctx == NULL)
|
||||
if (hash->ctx == NULL) {
|
||||
EVP_MD_meth_free(md);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
EVP_MD_meth_free(hash->md);
|
||||
hash->md = md;
|
||||
|
||||
/* These are taken from SP 800-90 10.1 Table 2 */
|
||||
hash->blocklen = EVP_MD_size(md);
|
||||
/* See SP800-57 Part1 Rev4 5.6.1 Table 3 */
|
||||
|
|
|
@ -183,6 +183,7 @@ static int drbg_hmac_generate(RAND_DRBG *drbg,
|
|||
|
||||
static int drbg_hmac_uninstantiate(RAND_DRBG *drbg)
|
||||
{
|
||||
EVP_MD_meth_free(drbg->data.hmac.md);
|
||||
HMAC_CTX_free(drbg->data.hmac.ctx);
|
||||
OPENSSL_cleanse(&drbg->data.hmac, sizeof(drbg->data.hmac));
|
||||
return 1;
|
||||
|
@ -197,11 +198,22 @@ static RAND_DRBG_METHOD drbg_hmac_meth = {
|
|||
|
||||
int drbg_hmac_init(RAND_DRBG *drbg)
|
||||
{
|
||||
const EVP_MD *md = NULL;
|
||||
EVP_MD *md = NULL;
|
||||
RAND_DRBG_HMAC *hmac = &drbg->data.hmac;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
/* Any approved digest is allowed - assume we pass digest (not NID_hmac*) */
|
||||
md = EVP_get_digestbynid(drbg->type);
|
||||
md = EVP_MD_meth_dup(EVP_get_digestbynid(drbg->type));
|
||||
#else
|
||||
/* TODO(3.0): Fill this out with the complete list of allowed digests */
|
||||
switch (drbg->type) {
|
||||
default:
|
||||
return 0;
|
||||
case NID_sha256:
|
||||
md = EVP_MD_fetch(drbg->libctx, "SHA256", "");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (md == NULL)
|
||||
return 0;
|
||||
|
||||
|
@ -209,11 +221,14 @@ int drbg_hmac_init(RAND_DRBG *drbg)
|
|||
|
||||
if (hmac->ctx == NULL) {
|
||||
hmac->ctx = HMAC_CTX_new();
|
||||
if (hmac->ctx == NULL)
|
||||
if (hmac->ctx == NULL) {
|
||||
EVP_MD_meth_free(md);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* These are taken from SP 800-90 10.1 Table 2 */
|
||||
EVP_MD_meth_free(hmac->md);
|
||||
hmac->md = md;
|
||||
hmac->blocklen = EVP_MD_size(md);
|
||||
/* See SP800-57 Part1 Rev4 5.6.1 Table 3 */
|
||||
|
|
|
@ -1339,7 +1339,8 @@ RAND_DRBG *OPENSSL_CTX_get0_public_drbg(OPENSSL_CTX *ctx)
|
|||
|
||||
drbg = CRYPTO_THREAD_get_local(&dgbl->public_drbg);
|
||||
if (drbg == NULL) {
|
||||
if (!ossl_init_thread_start(NULL, NULL, drbg_delete_thread_state))
|
||||
ctx = openssl_ctx_get_concrete(ctx);
|
||||
if (!ossl_init_thread_start(NULL, ctx, drbg_delete_thread_state))
|
||||
return NULL;
|
||||
drbg = drbg_setup(ctx, dgbl->master_drbg, RAND_DRBG_TYPE_PUBLIC);
|
||||
CRYPTO_THREAD_set_local(&dgbl->public_drbg, drbg);
|
||||
|
@ -1366,7 +1367,8 @@ RAND_DRBG *OPENSSL_CTX_get0_private_drbg(OPENSSL_CTX *ctx)
|
|||
|
||||
drbg = CRYPTO_THREAD_get_local(&dgbl->private_drbg);
|
||||
if (drbg == NULL) {
|
||||
if (!ossl_init_thread_start(NULL, NULL, drbg_delete_thread_state))
|
||||
ctx = openssl_ctx_get_concrete(ctx);
|
||||
if (!ossl_init_thread_start(NULL, ctx, drbg_delete_thread_state))
|
||||
return NULL;
|
||||
drbg = drbg_setup(ctx, dgbl->master_drbg, RAND_DRBG_TYPE_PRIVATE);
|
||||
CRYPTO_THREAD_set_local(&dgbl->private_drbg, drbg);
|
||||
|
|
|
@ -24,8 +24,8 @@ typedef struct crng_test_global_st {
|
|||
RAND_POOL *crngt_pool;
|
||||
} CRNG_TEST_GLOBAL;
|
||||
|
||||
int (*crngt_get_entropy)(OPENSSL_CTX *, unsigned char *, unsigned char *,
|
||||
unsigned int *)
|
||||
int (*crngt_get_entropy)(OPENSSL_CTX *, RAND_POOL *, unsigned char *,
|
||||
unsigned char *, unsigned int *)
|
||||
= &rand_crngt_get_entropy_cb;
|
||||
|
||||
static void rand_crng_ossl_ctx_free(void *vcrngt_glob)
|
||||
|
@ -49,7 +49,8 @@ static void *rand_crng_ossl_ctx_new(OPENSSL_CTX *ctx)
|
|||
OPENSSL_free(crngt_glob);
|
||||
return NULL;
|
||||
}
|
||||
if (crngt_get_entropy(ctx, buf, crngt_glob->crngt_prev, NULL)) {
|
||||
if (crngt_get_entropy(ctx, crngt_glob->crngt_pool, buf,
|
||||
crngt_glob->crngt_prev, NULL)) {
|
||||
OPENSSL_cleanse(buf, sizeof(buf));
|
||||
return crngt_glob;
|
||||
}
|
||||
|
@ -64,6 +65,7 @@ static const OPENSSL_CTX_METHOD rand_crng_ossl_ctx_method = {
|
|||
};
|
||||
|
||||
int rand_crngt_get_entropy_cb(OPENSSL_CTX *ctx,
|
||||
RAND_POOL *pool,
|
||||
unsigned char *buf,
|
||||
unsigned char *md,
|
||||
unsigned int *md_size)
|
||||
|
@ -71,20 +73,21 @@ int rand_crngt_get_entropy_cb(OPENSSL_CTX *ctx,
|
|||
int r;
|
||||
size_t n;
|
||||
unsigned char *p;
|
||||
CRNG_TEST_GLOBAL *crngt_glob
|
||||
= openssl_ctx_get_data(ctx, OPENSSL_CTX_RAND_CRNGT_INDEX,
|
||||
&rand_crng_ossl_ctx_method);
|
||||
|
||||
if (crngt_glob == NULL)
|
||||
if (pool == NULL)
|
||||
return 0;
|
||||
|
||||
n = rand_pool_acquire_entropy(crngt_glob->crngt_pool);
|
||||
n = rand_pool_acquire_entropy(pool);
|
||||
if (n >= CRNGT_BUFSIZ) {
|
||||
p = rand_pool_detach(crngt_glob->crngt_pool);
|
||||
r = EVP_Digest(p, CRNGT_BUFSIZ, md, md_size, EVP_sha256(), NULL);
|
||||
EVP_MD *fmd = EVP_MD_fetch(ctx, "SHA256", "");
|
||||
if (fmd == NULL)
|
||||
return 0;
|
||||
p = rand_pool_detach(pool);
|
||||
r = EVP_Digest(p, CRNGT_BUFSIZ, md, md_size, fmd, NULL);
|
||||
if (r != 0)
|
||||
memcpy(buf, p, CRNGT_BUFSIZ);
|
||||
rand_pool_reattach(crngt_glob->crngt_pool, p);
|
||||
rand_pool_reattach(pool, p);
|
||||
EVP_MD_meth_free(fmd);
|
||||
return r;
|
||||
}
|
||||
return 0;
|
||||
|
@ -112,7 +115,8 @@ size_t rand_crngt_get_entropy(RAND_DRBG *drbg,
|
|||
|
||||
while ((q = rand_pool_bytes_needed(pool, 1)) > 0 && attempts-- > 0) {
|
||||
s = q > sizeof(buf) ? sizeof(buf) : q;
|
||||
if (!crngt_get_entropy(drbg->libctx, buf, md, &sz)
|
||||
if (!crngt_get_entropy(drbg->libctx, crngt_glob->crngt_pool, buf, md,
|
||||
&sz)
|
||||
|| memcmp(crngt_glob->crngt_prev, md, sz) == 0
|
||||
|| !rand_pool_add(pool, buf, s, s * 8))
|
||||
goto err;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
# include <openssl/ec.h>
|
||||
# include <openssl/rand_drbg.h>
|
||||
# include "internal/tsan_assist.h"
|
||||
# include "internal/rand_int.h"
|
||||
|
||||
# include "internal/numbers.h"
|
||||
|
||||
|
@ -129,7 +130,7 @@ typedef struct rand_drbg_method_st {
|
|||
#define HASH_PRNG_MAX_SEEDLEN (888/8)
|
||||
|
||||
typedef struct rand_drbg_hash_st {
|
||||
const EVP_MD *md;
|
||||
EVP_MD *md;
|
||||
EVP_MD_CTX *ctx;
|
||||
size_t blocklen;
|
||||
unsigned char V[HASH_PRNG_MAX_SEEDLEN];
|
||||
|
@ -139,7 +140,7 @@ typedef struct rand_drbg_hash_st {
|
|||
} RAND_DRBG_HASH;
|
||||
|
||||
typedef struct rand_drbg_hmac_st {
|
||||
const EVP_MD *md;
|
||||
EVP_MD *md;
|
||||
HMAC_CTX *ctx;
|
||||
size_t blocklen;
|
||||
unsigned char K[EVP_MAX_MD_SIZE];
|
||||
|
@ -152,7 +153,7 @@ typedef struct rand_drbg_hmac_st {
|
|||
typedef struct rand_drbg_ctr_st {
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
EVP_CIPHER_CTX *ctx_df;
|
||||
const EVP_CIPHER *cipher;
|
||||
EVP_CIPHER *cipher;
|
||||
size_t keylen;
|
||||
unsigned char K[32];
|
||||
unsigned char V[16];
|
||||
|
@ -336,10 +337,11 @@ int drbg_hmac_init(RAND_DRBG *drbg);
|
|||
* Entropy call back for the FIPS 140-2 section 4.9.2 Conditional Tests.
|
||||
* These need to be exposed for the unit tests.
|
||||
*/
|
||||
int rand_crngt_get_entropy_cb(OPENSSL_CTX *ctx, unsigned char *buf,
|
||||
unsigned char *md, unsigned int *md_size);
|
||||
extern int (*crngt_get_entropy)(OPENSSL_CTX *ctx, unsigned char *buf,
|
||||
unsigned char *md,
|
||||
int rand_crngt_get_entropy_cb(OPENSSL_CTX *ctx, RAND_POOL *pool,
|
||||
unsigned char *buf, unsigned char *md,
|
||||
unsigned int *md_size);
|
||||
extern int (*crngt_get_entropy)(OPENSSL_CTX *ctx, RAND_POOL *pool,
|
||||
unsigned char *buf, unsigned char *md,
|
||||
unsigned int *md_size);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -285,7 +285,7 @@ static ssize_t syscall_random(void *buf, size_t buflen)
|
|||
|
||||
if (getentropy != NULL)
|
||||
return getentropy(buf, buflen) == 0 ? (ssize_t)buflen : -1;
|
||||
# else
|
||||
# elif !defined(FIPS_MODE)
|
||||
union {
|
||||
void *p;
|
||||
int (*f)(void *buffer, size_t length);
|
||||
|
|
|
@ -162,7 +162,7 @@ int rand_pool_add_additional_data(RAND_POOL *pool)
|
|||
return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);
|
||||
}
|
||||
|
||||
# if !OPENSSL_API_1_1_0
|
||||
# if !OPENSSL_API_1_1_0 && !defined(FIPS_MODE)
|
||||
int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
RAND_poll();
|
||||
|
|
|
@ -371,13 +371,13 @@ IF[{- !$disabled{tests} -}]
|
|||
DEPEND[recordlentest]=../libcrypto ../libssl libtestutil.a
|
||||
|
||||
SOURCE[drbgtest]=drbgtest.c
|
||||
INCLUDE[drbgtest]=../include ../apps/include
|
||||
INCLUDE[drbgtest]=../include ../apps/include ../crypto/include
|
||||
DEPEND[drbgtest]=../libcrypto.a libtestutil.a
|
||||
|
||||
SOURCE[drbg_cavs_test]=drbg_cavs_test.c drbg_cavs_data_ctr.c \
|
||||
drbg_cavs_data_hash.c drbg_cavs_data_hmac.c
|
||||
|
||||
INCLUDE[drbg_cavs_test]=../include ../apps/include . ..
|
||||
INCLUDE[drbg_cavs_test]=../include ../apps/include . .. ../crypto/include
|
||||
DEPEND[drbg_cavs_test]=../libcrypto libtestutil.a
|
||||
|
||||
SOURCE[x509_dup_cert_test]=x509_dup_cert_test.c
|
||||
|
|
|
@ -1264,8 +1264,8 @@ static const size_t crngt_num_cases = 6;
|
|||
|
||||
static size_t crngt_case, crngt_idx;
|
||||
|
||||
static int crngt_entropy_cb(OPENSSL_CTX *ctx, unsigned char *buf,
|
||||
unsigned char *md,
|
||||
static int crngt_entropy_cb(OPENSSL_CTX *ctx, RAND_POOL *pool,
|
||||
unsigned char *buf, unsigned char *md,
|
||||
unsigned int *md_size)
|
||||
{
|
||||
size_t i, z;
|
||||
|
|
Loading…
Reference in a new issue