Path: blob/main/crypto/openssl/providers/implementations/rands/test_rng.c
48383 views
/*1* Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89#include <string.h>10#include <stdlib.h>11#include <openssl/core_dispatch.h>12#include <openssl/e_os2.h>13#include <openssl/params.h>14#include <openssl/core_names.h>15#include <openssl/evp.h>16#include <openssl/err.h>17#include <openssl/randerr.h>18#include "prov/securitycheck.h"19#include "prov/providercommon.h"20#include "prov/provider_ctx.h"21#include "prov/provider_util.h"22#include "prov/implementations.h"2324static OSSL_FUNC_rand_newctx_fn test_rng_new;25static OSSL_FUNC_rand_freectx_fn test_rng_free;26static OSSL_FUNC_rand_instantiate_fn test_rng_instantiate;27static OSSL_FUNC_rand_uninstantiate_fn test_rng_uninstantiate;28static OSSL_FUNC_rand_generate_fn test_rng_generate;29static OSSL_FUNC_rand_reseed_fn test_rng_reseed;30static OSSL_FUNC_rand_nonce_fn test_rng_nonce;31static OSSL_FUNC_rand_settable_ctx_params_fn test_rng_settable_ctx_params;32static OSSL_FUNC_rand_set_ctx_params_fn test_rng_set_ctx_params;33static OSSL_FUNC_rand_gettable_ctx_params_fn test_rng_gettable_ctx_params;34static OSSL_FUNC_rand_get_ctx_params_fn test_rng_get_ctx_params;35static OSSL_FUNC_rand_verify_zeroization_fn test_rng_verify_zeroization;36static OSSL_FUNC_rand_enable_locking_fn test_rng_enable_locking;37static OSSL_FUNC_rand_lock_fn test_rng_lock;38static OSSL_FUNC_rand_unlock_fn test_rng_unlock;39static OSSL_FUNC_rand_get_seed_fn test_rng_get_seed;4041typedef struct {42void *provctx;43unsigned int generate;44int state;45unsigned int strength;46size_t max_request;47unsigned char *entropy, *nonce;48size_t entropy_len, entropy_pos, nonce_len;49CRYPTO_RWLOCK *lock;50uint32_t seed;51} PROV_TEST_RNG;5253static void *test_rng_new(void *provctx, void *parent,54const OSSL_DISPATCH *parent_dispatch)55{56PROV_TEST_RNG *t;5758t = OPENSSL_zalloc(sizeof(*t));59if (t == NULL)60return NULL;6162t->max_request = INT_MAX;63t->provctx = provctx;64t->state = EVP_RAND_STATE_UNINITIALISED;65return t;66}6768static void test_rng_free(void *vtest)69{70PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;7172if (t == NULL)73return;74OPENSSL_free(t->entropy);75OPENSSL_free(t->nonce);76CRYPTO_THREAD_lock_free(t->lock);77OPENSSL_free(t);78}7980static int test_rng_instantiate(void *vtest, unsigned int strength,81int prediction_resistance,82const unsigned char *pstr, size_t pstr_len,83const OSSL_PARAM params[])84{85PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;8687if (!test_rng_set_ctx_params(t, params) || strength > t->strength)88return 0;8990t->state = EVP_RAND_STATE_READY;91t->entropy_pos = 0;92t->seed = 221953166; /* Value doesn't matter, so long as it isn't zero */9394return 1;95}9697static int test_rng_uninstantiate(void *vtest)98{99PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;100101t->entropy_pos = 0;102t->state = EVP_RAND_STATE_UNINITIALISED;103return 1;104}105106static unsigned char gen_byte(PROV_TEST_RNG *t)107{108uint32_t n;109110/*111* Implement the 32 bit xorshift as suggested by George Marsaglia in:112* https://doi.org/10.18637/jss.v008.i14113*114* This is a very fast PRNG so there is no need to extract bytes one at a115* time and use the entire value each time.116*/117n = t->seed;118n ^= n << 13;119n ^= n >> 17;120n ^= n << 5;121t->seed = n;122123return n & 0xff;124}125126static int test_rng_generate(void *vtest, unsigned char *out, size_t outlen,127unsigned int strength, int prediction_resistance,128const unsigned char *adin, size_t adin_len)129{130PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;131size_t i;132133if (strength > t->strength)134return 0;135if (t->generate) {136for (i = 0; i < outlen; i++)137out[i] = gen_byte(t);138} else {139if (t->entropy_len - t->entropy_pos < outlen)140return 0;141142memcpy(out, t->entropy + t->entropy_pos, outlen);143t->entropy_pos += outlen;144}145return 1;146}147148static int test_rng_reseed(ossl_unused void *vtest,149ossl_unused int prediction_resistance,150ossl_unused const unsigned char *ent,151ossl_unused size_t ent_len,152ossl_unused const unsigned char *adin,153ossl_unused size_t adin_len)154{155return 1;156}157158static size_t test_rng_nonce(void *vtest, unsigned char *out,159unsigned int strength, size_t min_noncelen,160size_t max_noncelen)161{162PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;163size_t i;164165if (strength > t->strength)166return 0;167168if (t->generate) {169for (i = 0; i < min_noncelen; i++)170out[i] = gen_byte(t);171return min_noncelen;172}173174if (t->nonce == NULL)175return 0;176i = t->nonce_len > max_noncelen ? max_noncelen : t->nonce_len;177if (out != NULL)178memcpy(out, t->nonce, i);179return i;180}181182static int test_rng_get_ctx_params(void *vtest, OSSL_PARAM params[])183{184PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;185OSSL_PARAM *p;186187p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STATE);188if (p != NULL && !OSSL_PARAM_set_int(p, t->state))189return 0;190191p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STRENGTH);192if (p != NULL && !OSSL_PARAM_set_int(p, t->strength))193return 0;194195p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST);196if (p != NULL && !OSSL_PARAM_set_size_t(p, t->max_request))197return 0;198199p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_GENERATE);200if (p != NULL && !OSSL_PARAM_set_uint(p, t->generate))201return 0;202203#ifdef FIPS_MODULE204p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_FIPS_APPROVED_INDICATOR);205if (p != NULL && !OSSL_PARAM_set_int(p, 0))206return 0;207#endif /* FIPS_MODULE */208return 1;209}210211static const OSSL_PARAM *test_rng_gettable_ctx_params(ossl_unused void *vtest,212ossl_unused void *provctx)213{214static const OSSL_PARAM known_gettable_ctx_params[] = {215OSSL_PARAM_int(OSSL_RAND_PARAM_STATE, NULL),216OSSL_PARAM_uint(OSSL_RAND_PARAM_STRENGTH, NULL),217OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL),218OSSL_PARAM_uint(OSSL_RAND_PARAM_GENERATE, NULL),219OSSL_FIPS_IND_GETTABLE_CTX_PARAM()220OSSL_PARAM_END221};222return known_gettable_ctx_params;223}224225static int test_rng_set_ctx_params(void *vtest, const OSSL_PARAM params[])226{227PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;228const OSSL_PARAM *p;229void *ptr = NULL;230size_t size = 0;231232if (ossl_param_is_empty(params))233return 1;234235p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_STRENGTH);236if (p != NULL && !OSSL_PARAM_get_uint(p, &t->strength))237return 0;238239p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_TEST_ENTROPY);240if (p != NULL) {241if (!OSSL_PARAM_get_octet_string(p, &ptr, 0, &size))242return 0;243OPENSSL_free(t->entropy);244t->entropy = ptr;245t->entropy_len = size;246t->entropy_pos = 0;247ptr = NULL;248}249250p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_TEST_NONCE);251if (p != NULL) {252if (!OSSL_PARAM_get_octet_string(p, &ptr, 0, &size))253return 0;254OPENSSL_free(t->nonce);255t->nonce = ptr;256t->nonce_len = size;257}258259p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_MAX_REQUEST);260if (p != NULL && !OSSL_PARAM_get_size_t(p, &t->max_request))261return 0;262263p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_GENERATE);264if (p != NULL && !OSSL_PARAM_get_uint(p, &t->generate))265return 0;266return 1;267}268269static const OSSL_PARAM *test_rng_settable_ctx_params(ossl_unused void *vtest,270ossl_unused void *provctx)271{272static const OSSL_PARAM known_settable_ctx_params[] = {273OSSL_PARAM_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY, NULL, 0),274OSSL_PARAM_octet_string(OSSL_RAND_PARAM_TEST_NONCE, NULL, 0),275OSSL_PARAM_uint(OSSL_RAND_PARAM_STRENGTH, NULL),276OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL),277OSSL_PARAM_uint(OSSL_RAND_PARAM_GENERATE, NULL),278OSSL_PARAM_END279};280return known_settable_ctx_params;281}282283static int test_rng_verify_zeroization(ossl_unused void *vtest)284{285return 1;286}287288static size_t test_rng_get_seed(void *vtest, unsigned char **pout,289int entropy, size_t min_len, size_t max_len,290ossl_unused int prediction_resistance,291ossl_unused const unsigned char *adin,292ossl_unused size_t adin_len)293{294PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;295296*pout = t->entropy;297return t->entropy_len > max_len ? max_len : t->entropy_len;298}299300static int test_rng_enable_locking(void *vtest)301{302PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;303304if (t != NULL && t->lock == NULL) {305t->lock = CRYPTO_THREAD_lock_new();306if (t->lock == NULL) {307ERR_raise(ERR_LIB_PROV, RAND_R_FAILED_TO_CREATE_LOCK);308return 0;309}310}311return 1;312}313314static int test_rng_lock(void *vtest)315{316PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;317318if (t == NULL || t->lock == NULL)319return 1;320return CRYPTO_THREAD_write_lock(t->lock);321}322323static void test_rng_unlock(void *vtest)324{325PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;326327if (t != NULL && t->lock != NULL)328CRYPTO_THREAD_unlock(t->lock);329}330331const OSSL_DISPATCH ossl_test_rng_functions[] = {332{ OSSL_FUNC_RAND_NEWCTX, (void(*)(void))test_rng_new },333{ OSSL_FUNC_RAND_FREECTX, (void(*)(void))test_rng_free },334{ OSSL_FUNC_RAND_INSTANTIATE,335(void(*)(void))test_rng_instantiate },336{ OSSL_FUNC_RAND_UNINSTANTIATE,337(void(*)(void))test_rng_uninstantiate },338{ OSSL_FUNC_RAND_GENERATE, (void(*)(void))test_rng_generate },339{ OSSL_FUNC_RAND_RESEED, (void(*)(void))test_rng_reseed },340{ OSSL_FUNC_RAND_NONCE, (void(*)(void))test_rng_nonce },341{ OSSL_FUNC_RAND_ENABLE_LOCKING, (void(*)(void))test_rng_enable_locking },342{ OSSL_FUNC_RAND_LOCK, (void(*)(void))test_rng_lock },343{ OSSL_FUNC_RAND_UNLOCK, (void(*)(void))test_rng_unlock },344{ OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS,345(void(*)(void))test_rng_settable_ctx_params },346{ OSSL_FUNC_RAND_SET_CTX_PARAMS, (void(*)(void))test_rng_set_ctx_params },347{ OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,348(void(*)(void))test_rng_gettable_ctx_params },349{ OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))test_rng_get_ctx_params },350{ OSSL_FUNC_RAND_VERIFY_ZEROIZATION,351(void(*)(void))test_rng_verify_zeroization },352{ OSSL_FUNC_RAND_GET_SEED, (void(*)(void))test_rng_get_seed },353OSSL_DISPATCH_END354};355356357