Path: blob/main/crypto/openssl/providers/implementations/rands/seed_src.c
48383 views
/*1* Copyright 2020-2023 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 <openssl/rand.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 <openssl/proverr.h>19#include "prov/implementations.h"20#include "prov/provider_ctx.h"21#include "crypto/rand.h"22#include "crypto/rand_pool.h"2324static OSSL_FUNC_rand_newctx_fn seed_src_new;25static OSSL_FUNC_rand_freectx_fn seed_src_free;26static OSSL_FUNC_rand_instantiate_fn seed_src_instantiate;27static OSSL_FUNC_rand_uninstantiate_fn seed_src_uninstantiate;28static OSSL_FUNC_rand_generate_fn seed_src_generate;29static OSSL_FUNC_rand_reseed_fn seed_src_reseed;30static OSSL_FUNC_rand_gettable_ctx_params_fn seed_src_gettable_ctx_params;31static OSSL_FUNC_rand_get_ctx_params_fn seed_src_get_ctx_params;32static OSSL_FUNC_rand_verify_zeroization_fn seed_src_verify_zeroization;33static OSSL_FUNC_rand_enable_locking_fn seed_src_enable_locking;34static OSSL_FUNC_rand_lock_fn seed_src_lock;35static OSSL_FUNC_rand_unlock_fn seed_src_unlock;36static OSSL_FUNC_rand_get_seed_fn seed_get_seed;37static OSSL_FUNC_rand_clear_seed_fn seed_clear_seed;3839typedef struct {40void *provctx;41int state;42} PROV_SEED_SRC;4344static void *seed_src_new(void *provctx, void *parent,45const OSSL_DISPATCH *parent_dispatch)46{47PROV_SEED_SRC *s;4849if (parent != NULL) {50ERR_raise(ERR_LIB_PROV, PROV_R_SEED_SOURCES_MUST_NOT_HAVE_A_PARENT);51return NULL;52}5354s = OPENSSL_zalloc(sizeof(*s));55if (s == NULL)56return NULL;5758s->provctx = provctx;59s->state = EVP_RAND_STATE_UNINITIALISED;60return s;61}6263static void seed_src_free(void *vseed)64{65OPENSSL_free(vseed);66}6768static int seed_src_instantiate(void *vseed, unsigned int strength,69int prediction_resistance,70const unsigned char *pstr, size_t pstr_len,71ossl_unused const OSSL_PARAM params[])72{73PROV_SEED_SRC *s = (PROV_SEED_SRC *)vseed;7475s->state = EVP_RAND_STATE_READY;76return 1;77}7879static int seed_src_uninstantiate(void *vseed)80{81PROV_SEED_SRC *s = (PROV_SEED_SRC *)vseed;8283s->state = EVP_RAND_STATE_UNINITIALISED;84return 1;85}8687static int seed_src_generate(void *vseed, unsigned char *out, size_t outlen,88unsigned int strength,89ossl_unused int prediction_resistance,90const unsigned char *adin,91size_t adin_len)92{93PROV_SEED_SRC *s = (PROV_SEED_SRC *)vseed;94size_t entropy_available;95RAND_POOL *pool;9697if (s->state != EVP_RAND_STATE_READY) {98ERR_raise(ERR_LIB_PROV,99s->state == EVP_RAND_STATE_ERROR ? PROV_R_IN_ERROR_STATE100: PROV_R_NOT_INSTANTIATED);101return 0;102}103104pool = ossl_rand_pool_new(strength, 1, outlen, outlen);105if (pool == NULL) {106ERR_raise(ERR_LIB_PROV, ERR_R_RAND_LIB);107return 0;108}109110/* Get entropy by polling system entropy sources. */111entropy_available = ossl_pool_acquire_entropy(pool);112113if (entropy_available > 0) {114if (!ossl_rand_pool_adin_mix_in(pool, adin, adin_len)) {115ossl_rand_pool_free(pool);116return 0;117}118memcpy(out, ossl_rand_pool_buffer(pool), ossl_rand_pool_length(pool));119}120121ossl_rand_pool_free(pool);122return entropy_available > 0;123}124125static int seed_src_reseed(void *vseed,126ossl_unused int prediction_resistance,127ossl_unused const unsigned char *ent,128ossl_unused size_t ent_len,129ossl_unused const unsigned char *adin,130ossl_unused size_t adin_len)131{132PROV_SEED_SRC *s = (PROV_SEED_SRC *)vseed;133134if (s->state != EVP_RAND_STATE_READY) {135ERR_raise(ERR_LIB_PROV,136s->state == EVP_RAND_STATE_ERROR ? PROV_R_IN_ERROR_STATE137: PROV_R_NOT_INSTANTIATED);138return 0;139}140return 1;141}142143static int seed_src_get_ctx_params(void *vseed, OSSL_PARAM params[])144{145PROV_SEED_SRC *s = (PROV_SEED_SRC *)vseed;146OSSL_PARAM *p;147148p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STATE);149if (p != NULL && !OSSL_PARAM_set_int(p, s->state))150return 0;151152p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STRENGTH);153if (p != NULL && !OSSL_PARAM_set_int(p, 1024))154return 0;155156p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST);157if (p != NULL && !OSSL_PARAM_set_size_t(p, 128))158return 0;159return 1;160}161162static const OSSL_PARAM *seed_src_gettable_ctx_params(ossl_unused void *vseed,163ossl_unused void *provctx)164{165static const OSSL_PARAM known_gettable_ctx_params[] = {166OSSL_PARAM_int(OSSL_RAND_PARAM_STATE, NULL),167OSSL_PARAM_uint(OSSL_RAND_PARAM_STRENGTH, NULL),168OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL),169OSSL_PARAM_END170};171return known_gettable_ctx_params;172}173174static int seed_src_verify_zeroization(ossl_unused void *vseed)175{176return 1;177}178179static size_t seed_get_seed(void *vseed, unsigned char **pout,180int entropy, size_t min_len, size_t max_len,181int prediction_resistance,182const unsigned char *adin, size_t adin_len)183{184size_t ret = 0;185size_t entropy_available = 0;186RAND_POOL *pool;187188pool = ossl_rand_pool_new(entropy, 1, min_len, max_len);189if (pool == NULL) {190ERR_raise(ERR_LIB_PROV, ERR_R_RAND_LIB);191return 0;192}193194/* Get entropy by polling system entropy sources. */195entropy_available = ossl_pool_acquire_entropy(pool);196197if (entropy_available > 0198&& ossl_rand_pool_adin_mix_in(pool, adin, adin_len)) {199ret = ossl_rand_pool_length(pool);200*pout = ossl_rand_pool_detach(pool);201} else {202ERR_raise(ERR_LIB_PROV, PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK);203}204ossl_rand_pool_free(pool);205return ret;206}207208static void seed_clear_seed(ossl_unused void *vdrbg,209unsigned char *out, size_t outlen)210{211OPENSSL_secure_clear_free(out, outlen);212}213214static int seed_src_enable_locking(ossl_unused void *vseed)215{216return 1;217}218219int seed_src_lock(ossl_unused void *vctx)220{221return 1;222}223224void seed_src_unlock(ossl_unused void *vctx)225{226}227228const OSSL_DISPATCH ossl_seed_src_functions[] = {229{ OSSL_FUNC_RAND_NEWCTX, (void(*)(void))seed_src_new },230{ OSSL_FUNC_RAND_FREECTX, (void(*)(void))seed_src_free },231{ OSSL_FUNC_RAND_INSTANTIATE,232(void(*)(void))seed_src_instantiate },233{ OSSL_FUNC_RAND_UNINSTANTIATE,234(void(*)(void))seed_src_uninstantiate },235{ OSSL_FUNC_RAND_GENERATE, (void(*)(void))seed_src_generate },236{ OSSL_FUNC_RAND_RESEED, (void(*)(void))seed_src_reseed },237{ OSSL_FUNC_RAND_ENABLE_LOCKING, (void(*)(void))seed_src_enable_locking },238{ OSSL_FUNC_RAND_LOCK, (void(*)(void))seed_src_lock },239{ OSSL_FUNC_RAND_UNLOCK, (void(*)(void))seed_src_unlock },240{ OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,241(void(*)(void))seed_src_gettable_ctx_params },242{ OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))seed_src_get_ctx_params },243{ OSSL_FUNC_RAND_VERIFY_ZEROIZATION,244(void(*)(void))seed_src_verify_zeroization },245{ OSSL_FUNC_RAND_GET_SEED, (void(*)(void))seed_get_seed },246{ OSSL_FUNC_RAND_CLEAR_SEED, (void(*)(void))seed_clear_seed },247OSSL_DISPATCH_END248};249250251