Add function to mix in an additional input into a RAND_POOL

It will be just xor-ed over the existing entropy
in the pool.

Reviewed-by: Paul Dale <ppzgs1@gmail.com>
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26128)
This commit is contained in:
Tomas Mraz 2024-12-06 16:22:42 +01:00
parent dc10ffc283
commit d992e8729e
8 changed files with 96 additions and 61 deletions

View File

@ -1203,6 +1203,7 @@ RAND_R_PERSONALISATION_STRING_TOO_LONG:116:personalisation string too long
RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED:133:\
prediction resistance not supported
RAND_R_PRNG_NOT_SEEDED:100:PRNG not seeded
RAND_R_RANDOM_POOL_IS_EMPTY:142:random pool is empty
RAND_R_RANDOM_POOL_OVERFLOW:125:random pool overflow
RAND_R_RANDOM_POOL_UNDERFLOW:134:random pool underflow
RAND_R_REQUEST_TOO_LARGE_FOR_DRBG:117:request too large for drbg

View File

@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
* Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* 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
@ -16,84 +16,86 @@
static const ERR_STRING_DATA RAND_str_reasons[] = {
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ADDITIONAL_INPUT_TOO_LONG),
"additional input too long"},
"additional input too long"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ALREADY_INSTANTIATED),
"already instantiated"},
"already instantiated"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ARGUMENT_OUT_OF_RANGE),
"argument out of range"},
"argument out of range"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_CANNOT_OPEN_FILE), "Cannot open file"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_DRBG_ALREADY_INITIALIZED),
"drbg already initialized"},
"drbg already initialized"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_DRBG_NOT_INITIALISED),
"drbg not initialised"},
"drbg not initialised"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ENTROPY_INPUT_TOO_LONG),
"entropy input too long"},
"entropy input too long"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ENTROPY_OUT_OF_RANGE),
"entropy out of range"},
"entropy out of range"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED),
"error entropy pool was ignored"},
"error entropy pool was ignored"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ERROR_INITIALISING_DRBG),
"error initialising drbg"},
"error initialising drbg"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ERROR_INSTANTIATING_DRBG),
"error instantiating drbg"},
"error instantiating drbg"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ERROR_RETRIEVING_ADDITIONAL_INPUT),
"error retrieving additional input"},
"error retrieving additional input"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ERROR_RETRIEVING_ENTROPY),
"error retrieving entropy"},
"error retrieving entropy"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ERROR_RETRIEVING_NONCE),
"error retrieving nonce"},
"error retrieving nonce"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_FAILED_TO_CREATE_LOCK),
"failed to create lock"},
"failed to create lock"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_FUNC_NOT_IMPLEMENTED),
"Function not implemented"},
"Function not implemented"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_FWRITE_ERROR), "Error writing file"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_GENERATE_ERROR), "generate error"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_INSUFFICIENT_DRBG_STRENGTH),
"insufficient drbg strength"},
"insufficient drbg strength"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_INTERNAL_ERROR), "internal error"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_INVALID_PROPERTY_QUERY),
"invalid property query"},
"invalid property query"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_IN_ERROR_STATE), "in error state"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_NOT_A_REGULAR_FILE),
"Not a regular file"},
"Not a regular file"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_NOT_INSTANTIATED), "not instantiated"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED),
"no drbg implementation selected"},
"no drbg implementation selected"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PARENT_LOCKING_NOT_ENABLED),
"parent locking not enabled"},
"parent locking not enabled"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PARENT_STRENGTH_TOO_WEAK),
"parent strength too weak"},
"parent strength too weak"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PERSONALISATION_STRING_TOO_LONG),
"personalisation string too long"},
"personalisation string too long"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED),
"prediction resistance not supported"},
"prediction resistance not supported"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PRNG_NOT_SEEDED), "PRNG not seeded"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_RANDOM_POOL_IS_EMPTY),
"random pool is empty"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_RANDOM_POOL_OVERFLOW),
"random pool overflow"},
"random pool overflow"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_RANDOM_POOL_UNDERFLOW),
"random pool underflow"},
"random pool underflow"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_REQUEST_TOO_LARGE_FOR_DRBG),
"request too large for drbg"},
"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_TOO_LITTLE_NONCE_REQUESTED),
"too little nonce requested"},
"too little nonce requested"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_TOO_MUCH_NONCE_REQUESTED),
"too much nonce requested"},
"too much nonce requested"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_CREATE_DRBG),
"unable to create drbg"},
"unable to create drbg"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_FETCH_DRBG),
"unable to fetch drbg"},
"unable to fetch drbg"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER),
"unable to get parent reseed prop counter"},
"unable to get parent reseed prop counter"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_GET_PARENT_STRENGTH),
"unable to get parent strength"},
"unable to get parent strength"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_LOCK_PARENT),
"unable to lock parent"},
"unable to lock parent"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNSUPPORTED_DRBG_FLAGS),
"unsupported drbg flags"},
"unsupported drbg flags"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNSUPPORTED_DRBG_TYPE),
"unsupported drbg type"},
"unsupported drbg type"},
{0, NULL}
};

View File

@ -406,3 +406,42 @@ int ossl_rand_pool_add_end(RAND_POOL *pool, size_t len, size_t entropy)
return 1;
}
/**
* @brief Mix in the additional input into an existing entropy in the pool
*
* @param pool A RAND_POOL to mix the additional input in
* @param adin A buffer with the additional input
* @param adin_len A length of the additional input
*
* @return 1 if there is any existing entropy in the pool so the additional input
* can be mixed in, 0 otherwise.
*/
int ossl_rand_pool_adin_mix_in(RAND_POOL *pool, const unsigned char *adin,
size_t adin_len)
{
if (adin == NULL || adin_len == 0)
/* Nothing to mix in -> success */
return 1;
if (pool->buffer == NULL) {
ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR);
return 0;
}
if (pool->len == 0) {
ERR_raise(ERR_LIB_RAND, RAND_R_RANDOM_POOL_IS_EMPTY);
return 0;
}
if (adin != NULL && adin_len > 0) {
size_t i;
/* xor the additional data into the pool */
for (i = 0; i < adin_len; ++i)
pool->buffer[i % pool->len] ^= adin[i];
}
return 1;
}

View File

@ -105,5 +105,7 @@ int ossl_rand_pool_add(RAND_POOL *pool,
const unsigned char *buffer, size_t len, size_t entropy);
unsigned char *ossl_rand_pool_add_begin(RAND_POOL *pool, size_t len);
int ossl_rand_pool_add_end(RAND_POOL *pool, size_t len, size_t entropy);
int ossl_rand_pool_adin_mix_in(RAND_POOL *pool, const unsigned char *adin,
size_t adin_len);
#endif /* OSSL_PROVIDER_RAND_POOL_H */

View File

@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
* Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* 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

View File

@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
* Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* 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
@ -51,6 +51,7 @@
# define RAND_R_PERSONALISATION_STRING_TOO_LONG 116
# define RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED 133
# define RAND_R_PRNG_NOT_SEEDED 100
# define RAND_R_RANDOM_POOL_IS_EMPTY 142
# define RAND_R_RANDOM_POOL_OVERFLOW 125
# define RAND_R_RANDOM_POOL_UNDERFLOW 134
# define RAND_R_REQUEST_TOO_LARGE_FOR_DRBG 117

View File

@ -88,8 +88,8 @@ static int seed_src_uninstantiate(void *vseed)
static int seed_src_generate(void *vseed, unsigned char *out, size_t outlen,
unsigned int strength,
ossl_unused int prediction_resistance,
ossl_unused const unsigned char *adin,
ossl_unused size_t adin_len)
const unsigned char *adin,
size_t adin_len)
{
PROV_SEED_SRC *s = (PROV_SEED_SRC *)vseed;
size_t entropy_available;
@ -111,8 +111,11 @@ static int seed_src_generate(void *vseed, unsigned char *out, size_t outlen,
/* Get entropy by polling system entropy sources. */
entropy_available = ossl_pool_acquire_entropy(pool);
if (entropy_available > 0)
if (entropy_available > 0) {
if (!ossl_rand_pool_adin_mix_in(pool, adin, adin_len))
return 0;
memcpy(out, ossl_rand_pool_buffer(pool), ossl_rand_pool_length(pool));
}
ossl_rand_pool_free(pool);
return entropy_available > 0;
@ -179,7 +182,6 @@ static size_t seed_get_seed(void *vseed, unsigned char **pout,
{
size_t ret = 0;
size_t entropy_available = 0;
size_t i;
RAND_POOL *pool;
pool = ossl_rand_pool_new(entropy, 1, min_len, max_len);
@ -191,13 +193,10 @@ static size_t seed_get_seed(void *vseed, unsigned char **pout,
/* Get entropy by polling system entropy sources. */
entropy_available = ossl_pool_acquire_entropy(pool);
if (entropy_available > 0) {
if (entropy_available > 0
&& ossl_rand_pool_adin_mix_in(pool, adin, adin_len)) {
ret = ossl_rand_pool_length(pool);
*pout = ossl_rand_pool_detach(pool);
/* xor the additional data into the output */
for (i = 0 ; i < adin_len ; ++i)
(*pout)[i % ret] ^= adin[i];
} else {
ERR_raise(ERR_LIB_PROV, PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK);
}

View File

@ -197,15 +197,10 @@ static int jitter_generate(void *vseed, unsigned char *out, size_t outlen,
/* Get entropy from jitter entropy library. */
entropy_available = ossl_prov_acquire_entropy_from_jitter(s, pool);
if (entropy_available > 0)
if (entropy_available > 0) {
if (!ossl_rand_pool_adin_mix_in(pool, adin, adin_len))
return 0;
memcpy(out, ossl_rand_pool_buffer(pool), ossl_rand_pool_length(pool));
if (adin != NULL && adin_len > 0) {
size_t i;
/* xor the additional data into the output */
for (i = 0; i < adin_len; ++i)
out[i % outlen] ^= adin[i];
}
ossl_rand_pool_free(pool);
@ -275,7 +270,6 @@ static size_t jitter_get_seed(void *vseed, unsigned char **pout,
{
size_t ret = 0;
size_t entropy_available = 0;
size_t i;
RAND_POOL *pool;
PROV_JITTER *s = (PROV_JITTER *)vseed;
@ -288,13 +282,10 @@ static size_t jitter_get_seed(void *vseed, unsigned char **pout,
/* Get entropy from jitter entropy library. */
entropy_available = ossl_prov_acquire_entropy_from_jitter(s, pool);
if (entropy_available > 0) {
if (entropy_available > 0
&& ossl_rand_pool_adin_mix_in(pool, adin, adin_len)) {
ret = ossl_rand_pool_length(pool);
*pout = ossl_rand_pool_detach(pool);
/* xor the additional data into the output */
for (i = 0; i < adin_len; ++i)
(*pout)[i % ret] ^= adin[i];
} else {
ERR_raise(ERR_LIB_PROV, PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK);
}