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
@ -68,6 +68,8 @@ static const ERR_STRING_DATA RAND_str_reasons[] = {
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_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"},
{ERR_PACK(ERR_LIB_RAND, 0, RAND_R_RANDOM_POOL_UNDERFLOW),

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);
}