diff options
Diffstat (limited to 'providers/implementations/rands/test_rng.c')
-rw-r--r-- | providers/implementations/rands/test_rng.c | 78 |
1 files changed, 68 insertions, 10 deletions
diff --git a/providers/implementations/rands/test_rng.c b/providers/implementations/rands/test_rng.c index 4e7fed0fc7b1..dc5339166567 100644 --- a/providers/implementations/rands/test_rng.c +++ b/providers/implementations/rands/test_rng.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 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 @@ -8,6 +8,7 @@ */ #include <string.h> +#include <stdlib.h> #include <openssl/core_dispatch.h> #include <openssl/e_os2.h> #include <openssl/params.h> @@ -15,6 +16,7 @@ #include <openssl/evp.h> #include <openssl/err.h> #include <openssl/randerr.h> +#include "prov/securitycheck.h" #include "prov/providercommon.h" #include "prov/provider_ctx.h" #include "prov/provider_util.h" @@ -39,12 +41,14 @@ static OSSL_FUNC_rand_get_seed_fn test_rng_get_seed; typedef struct { void *provctx; + unsigned int generate; int state; unsigned int strength; size_t max_request; unsigned char *entropy, *nonce; size_t entropy_len, entropy_pos, nonce_len; CRYPTO_RWLOCK *lock; + uint32_t seed; } PROV_TEST_RNG; static void *test_rng_new(void *provctx, void *parent, @@ -86,6 +90,7 @@ static int test_rng_instantiate(void *vtest, unsigned int strength, t->state = EVP_RAND_STATE_READY; t->entropy_pos = 0; + t->seed = 221953166; /* Value doesn't matter, so long as it isn't zero */ return 1; } @@ -99,16 +104,45 @@ static int test_rng_uninstantiate(void *vtest) return 1; } +static unsigned char gen_byte(PROV_TEST_RNG *t) +{ + uint32_t n; + + /* + * Implement the 32 bit xorshift as suggested by George Marsaglia in: + * https://doi.org/10.18637/jss.v008.i14 + * + * This is a very fast PRNG so there is no need to extract bytes one at a + * time and use the entire value each time. + */ + n = t->seed; + n ^= n << 13; + n ^= n >> 17; + n ^= n << 5; + t->seed = n; + + return n & 0xff; +} + static int test_rng_generate(void *vtest, unsigned char *out, size_t outlen, unsigned int strength, int prediction_resistance, const unsigned char *adin, size_t adin_len) { PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest; + size_t i; - if (strength > t->strength || t->entropy_len - t->entropy_pos < outlen) + if (strength > t->strength) return 0; - memcpy(out, t->entropy + t->entropy_pos, outlen); - t->entropy_pos += outlen; + if (t->generate) { + for (i = 0; i < outlen; i++) + out[i] = gen_byte(t); + } else { + if (t->entropy_len - t->entropy_pos < outlen) + return 0; + + memcpy(out, t->entropy + t->entropy_pos, outlen); + t->entropy_pos += outlen; + } return 1; } @@ -123,15 +157,23 @@ static int test_rng_reseed(ossl_unused void *vtest, } static size_t test_rng_nonce(void *vtest, unsigned char *out, - unsigned int strength, - ossl_unused size_t min_noncelen, + unsigned int strength, size_t min_noncelen, ossl_unused size_t max_noncelen) { PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest; + size_t i; - if (t->nonce == NULL || strength > t->strength) + if (strength > t->strength) return 0; + if (t->generate) { + for (i = 0; i < min_noncelen; i++) + out[i] = gen_byte(t); + return min_noncelen; + } + + if (t->nonce == NULL) + return 0; if (out != NULL) memcpy(out, t->nonce, t->nonce_len); return t->nonce_len; @@ -153,6 +195,16 @@ static int test_rng_get_ctx_params(void *vtest, OSSL_PARAM params[]) p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST); if (p != NULL && !OSSL_PARAM_set_size_t(p, t->max_request)) return 0; + + p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_GENERATE); + if (p != NULL && !OSSL_PARAM_set_uint(p, t->generate)) + return 0; + +#ifdef FIPS_MODULE + p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_FIPS_APPROVED_INDICATOR); + if (p != NULL && !OSSL_PARAM_set_int(p, 0)) + return 0; +#endif /* FIPS_MODULE */ return 1; } @@ -163,6 +215,8 @@ static const OSSL_PARAM *test_rng_gettable_ctx_params(ossl_unused void *vtest, OSSL_PARAM_int(OSSL_RAND_PARAM_STATE, NULL), OSSL_PARAM_uint(OSSL_RAND_PARAM_STRENGTH, NULL), OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL), + OSSL_PARAM_uint(OSSL_RAND_PARAM_GENERATE, NULL), + OSSL_FIPS_IND_GETTABLE_CTX_PARAM() OSSL_PARAM_END }; return known_gettable_ctx_params; @@ -175,7 +229,7 @@ static int test_rng_set_ctx_params(void *vtest, const OSSL_PARAM params[]) void *ptr = NULL; size_t size = 0; - if (params == NULL) + if (ossl_param_is_empty(params)) return 1; p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_STRENGTH); @@ -203,9 +257,12 @@ static int test_rng_set_ctx_params(void *vtest, const OSSL_PARAM params[]) } p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_MAX_REQUEST); - if (p != NULL && !OSSL_PARAM_get_size_t(p, &t->max_request)) + if (p != NULL && !OSSL_PARAM_get_size_t(p, &t->max_request)) return 0; + p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_GENERATE); + if (p != NULL && !OSSL_PARAM_get_uint(p, &t->generate)) + return 0; return 1; } @@ -217,6 +274,7 @@ static const OSSL_PARAM *test_rng_settable_ctx_params(ossl_unused void *vtest, OSSL_PARAM_octet_string(OSSL_RAND_PARAM_TEST_NONCE, NULL, 0), OSSL_PARAM_uint(OSSL_RAND_PARAM_STRENGTH, NULL), OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL), + OSSL_PARAM_uint(OSSL_RAND_PARAM_GENERATE, NULL), OSSL_PARAM_END }; return known_settable_ctx_params; @@ -292,5 +350,5 @@ const OSSL_DISPATCH ossl_test_rng_functions[] = { { OSSL_FUNC_RAND_VERIFY_ZEROIZATION, (void(*)(void))test_rng_verify_zeroization }, { OSSL_FUNC_RAND_GET_SEED, (void(*)(void))test_rng_get_seed }, - { 0, NULL } + OSSL_DISPATCH_END }; |