Path: blob/main/crypto/openssl/providers/implementations/rands/drbg_hmac.c
108031 views
/*1* Copyright 2011-2026 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 <stdlib.h>10#include <string.h>11#include <openssl/crypto.h>12#include <openssl/err.h>13#include <openssl/rand.h>14#include <openssl/proverr.h>15#include "internal/thread_once.h"16#include "prov/providercommon.h"17#include "prov/implementations.h"18#include "prov/provider_ctx.h"19#include "prov/hmac_drbg.h"20#include "drbg_local.h"21#include "crypto/evp.h"22#include "crypto/evp/evp_local.h"23#include "internal/provider.h"2425static OSSL_FUNC_rand_newctx_fn drbg_hmac_new_wrapper;26static OSSL_FUNC_rand_freectx_fn drbg_hmac_free;27static OSSL_FUNC_rand_instantiate_fn drbg_hmac_instantiate_wrapper;28static OSSL_FUNC_rand_uninstantiate_fn drbg_hmac_uninstantiate_wrapper;29static OSSL_FUNC_rand_generate_fn drbg_hmac_generate_wrapper;30static OSSL_FUNC_rand_reseed_fn drbg_hmac_reseed_wrapper;31static OSSL_FUNC_rand_settable_ctx_params_fn drbg_hmac_settable_ctx_params;32static OSSL_FUNC_rand_set_ctx_params_fn drbg_hmac_set_ctx_params;33static OSSL_FUNC_rand_gettable_ctx_params_fn drbg_hmac_gettable_ctx_params;34static OSSL_FUNC_rand_get_ctx_params_fn drbg_hmac_get_ctx_params;35static OSSL_FUNC_rand_verify_zeroization_fn drbg_hmac_verify_zeroization;3637static int drbg_hmac_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[]);3839/*40* Called twice by SP800-90Ar1 10.1.2.2 HMAC_DRBG_Update_Process.41*42* hmac is an object that holds the input/output Key and Value (K and V).43* inbyte is 0x00 on the first call and 0x01 on the second call.44* in1, in2, in3 are optional inputs that can be NULL.45* in1len, in2len, in3len are the lengths of the input buffers.46*47* The returned K,V is:48* hmac->K = HMAC(hmac->K, hmac->V || inbyte || [in1] || [in2] || [in3])49* hmac->V = HMAC(hmac->K, hmac->V)50*51* Returns zero if an error occurs otherwise it returns 1.52*/53static int do_hmac(PROV_DRBG_HMAC *hmac, unsigned char inbyte,54const unsigned char *in1, size_t in1len,55const unsigned char *in2, size_t in2len,56const unsigned char *in3, size_t in3len)57{58EVP_MAC_CTX *ctx = hmac->ctx;5960if (!EVP_MAC_init(ctx, hmac->K, hmac->blocklen, NULL)61/* K = HMAC(K, V || inbyte || [in1] || [in2] || [in3]) */62|| !EVP_MAC_update(ctx, hmac->V, hmac->blocklen)63|| !EVP_MAC_update(ctx, &inbyte, 1)64|| !(in1 == NULL || in1len == 0 || EVP_MAC_update(ctx, in1, in1len))65|| !(in2 == NULL || in2len == 0 || EVP_MAC_update(ctx, in2, in2len))66|| !(in3 == NULL || in3len == 0 || EVP_MAC_update(ctx, in3, in3len))67|| !EVP_MAC_final(ctx, hmac->K, NULL, sizeof(hmac->K)))68return 0;6970/* V = HMAC(K, V) */71return EVP_MAC_init(ctx, hmac->K, hmac->blocklen, NULL)72&& EVP_MAC_update(ctx, hmac->V, hmac->blocklen)73&& EVP_MAC_final(ctx, hmac->V, NULL, sizeof(hmac->V));74}7576/*77* SP800-90Ar1 10.1.2.2 HMAC_DRBG_Update_Process78*79*80* Updates the drbg objects Key(K) and Value(V) using the following algorithm:81* K,V = do_hmac(hmac, 0, in1, in2, in3)82* if (any input is not NULL)83* K,V = do_hmac(hmac, 1, in1, in2, in3)84*85* where in1, in2, in3 are optional input buffers that can be NULL.86* in1len, in2len, in3len are the lengths of the input buffers.87*88* Returns zero if an error occurs otherwise it returns 1.89*/90static int drbg_hmac_update(PROV_DRBG_HMAC *hmac,91const unsigned char *in1, size_t in1len,92const unsigned char *in2, size_t in2len,93const unsigned char *in3, size_t in3len)94{95/* (Steps 1-2) K = HMAC(K, V||0x00||provided_data). V = HMAC(K,V) */96if (!do_hmac(hmac, 0x00, in1, in1len, in2, in2len, in3, in3len))97return 0;98/* (Step 3) If provided_data == NULL then return (K,V) */99if (in1len == 0 && in2len == 0 && in3len == 0)100return 1;101/* (Steps 4-5) K = HMAC(K, V||0x01||provided_data). V = HMAC(K,V) */102return do_hmac(hmac, 0x01, in1, in1len, in2, in2len, in3, in3len);103}104105/*106* SP800-90Ar1 10.1.2.3 HMAC_DRBG_Instantiate_Process:107*108* This sets the drbg Key (K) to all zeros, and Value (V) to all 1's.109* and then calls (K,V) = drbg_hmac_update() with input parameters:110* ent = entropy data (Can be NULL) of length ent_len.111* nonce = nonce data (Can be NULL) of length nonce_len.112* pstr = personalization data (Can be NULL) of length pstr_len.113*114* Returns zero if an error occurs otherwise it returns 1.115*/116int ossl_drbg_hmac_init(PROV_DRBG_HMAC *hmac,117const unsigned char *ent, size_t ent_len,118const unsigned char *nonce, size_t nonce_len,119const unsigned char *pstr, size_t pstr_len)120{121if (hmac->ctx == NULL) {122ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MAC);123return 0;124}125126/* (Step 2) Key = 0x00 00...00 */127memset(hmac->K, 0x00, hmac->blocklen);128/* (Step 3) V = 0x01 01...01 */129memset(hmac->V, 0x01, hmac->blocklen);130/* (Step 4) (K,V) = HMAC_DRBG_Update(entropy||nonce||pers string, K, V) */131return drbg_hmac_update(hmac, ent, ent_len, nonce, nonce_len, pstr,132pstr_len);133}134static int drbg_hmac_instantiate(PROV_DRBG *drbg,135const unsigned char *ent, size_t ent_len,136const unsigned char *nonce, size_t nonce_len,137const unsigned char *pstr, size_t pstr_len)138{139return ossl_drbg_hmac_init((PROV_DRBG_HMAC *)drbg->data, ent, ent_len,140nonce, nonce_len, pstr, pstr_len);141}142143static int drbg_hmac_instantiate_wrapper(void *vdrbg, unsigned int strength,144int prediction_resistance,145const unsigned char *pstr,146size_t pstr_len,147const OSSL_PARAM params[])148{149PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;150int ret = 0;151152if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))153return 0;154155if (!ossl_prov_is_running()156|| !drbg_hmac_set_ctx_params_locked(drbg, params))157goto err;158ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,159pstr, pstr_len);160err:161if (drbg->lock != NULL)162CRYPTO_THREAD_unlock(drbg->lock);163return ret;164}165166/*167* SP800-90Ar1 10.1.2.4 HMAC_DRBG_Reseed_Process:168*169* Reseeds the drbg's Key (K) and Value (V) by calling170* (K,V) = drbg_hmac_update() with the following input parameters:171* ent = entropy input data (Can be NULL) of length ent_len.172* adin = additional input data (Can be NULL) of length adin_len.173*174* Returns zero if an error occurs otherwise it returns 1.175*/176static int drbg_hmac_reseed(PROV_DRBG *drbg,177const unsigned char *ent, size_t ent_len,178const unsigned char *adin, size_t adin_len)179{180PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)drbg->data;181182/* (Step 2) (K,V) = HMAC_DRBG_Update(entropy||additional_input, K, V) */183return drbg_hmac_update(hmac, ent, ent_len, adin, adin_len, NULL, 0);184}185186static int drbg_hmac_reseed_wrapper(void *vdrbg, int prediction_resistance,187const unsigned char *ent, size_t ent_len,188const unsigned char *adin, size_t adin_len)189{190PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;191192return ossl_prov_drbg_reseed(drbg, prediction_resistance, ent, ent_len,193adin, adin_len);194}195196/*197* SP800-90Ar1 10.1.2.5 HMAC_DRBG_Generate_Process:198*199* Generates pseudo random bytes and updates the internal K,V for the drbg.200* out is a buffer to fill with outlen bytes of pseudo random data.201* adin is an additional_input string of size adin_len that may be NULL.202*203* Returns zero if an error occurs otherwise it returns 1.204*/205int ossl_drbg_hmac_generate(PROV_DRBG_HMAC *hmac,206unsigned char *out, size_t outlen,207const unsigned char *adin, size_t adin_len)208{209EVP_MAC_CTX *ctx = hmac->ctx;210const unsigned char *temp = hmac->V;211212/* (Step 2) if adin != NULL then (K,V) = HMAC_DRBG_Update(adin, K, V) */213if (adin != NULL214&& adin_len > 0215&& !drbg_hmac_update(hmac, adin, adin_len, NULL, 0, NULL, 0))216return 0;217218/*219* (Steps 3-5) temp = NULL220* while (len(temp) < outlen) {221* V = HMAC(K, V)222* temp = temp || V223* }224*/225for (;;) {226if (!EVP_MAC_init(ctx, hmac->K, hmac->blocklen, NULL)227|| !EVP_MAC_update(ctx, temp, hmac->blocklen))228return 0;229230if (outlen > hmac->blocklen) {231if (!EVP_MAC_final(ctx, out, NULL, outlen))232return 0;233temp = out;234} else {235if (!EVP_MAC_final(ctx, hmac->V, NULL, sizeof(hmac->V)))236return 0;237memcpy(out, hmac->V, outlen);238break;239}240out += hmac->blocklen;241outlen -= hmac->blocklen;242}243/* (Step 6) (K,V) = HMAC_DRBG_Update(adin, K, V) */244if (!drbg_hmac_update(hmac, adin, adin_len, NULL, 0, NULL, 0))245return 0;246247return 1;248}249250static int drbg_hmac_generate(PROV_DRBG *drbg,251unsigned char *out, size_t outlen,252const unsigned char *adin, size_t adin_len)253{254return ossl_drbg_hmac_generate((PROV_DRBG_HMAC *)drbg->data, out, outlen,255adin, adin_len);256}257258static int drbg_hmac_generate_wrapper(void *vdrbg,259unsigned char *out, size_t outlen, unsigned int strength,260int prediction_resistance, const unsigned char *adin, size_t adin_len)261{262PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;263264return ossl_prov_drbg_generate(drbg, out, outlen, strength,265prediction_resistance, adin, adin_len);266}267268static int drbg_hmac_uninstantiate(PROV_DRBG *drbg)269{270PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)drbg->data;271272OPENSSL_cleanse(hmac->K, sizeof(hmac->K));273OPENSSL_cleanse(hmac->V, sizeof(hmac->V));274return ossl_prov_drbg_uninstantiate(drbg);275}276277static int drbg_hmac_uninstantiate_wrapper(void *vdrbg)278{279PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;280int ret;281282if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))283return 0;284285ret = drbg_hmac_uninstantiate(drbg);286287if (drbg->lock != NULL)288CRYPTO_THREAD_unlock(drbg->lock);289290return ret;291}292293static int drbg_hmac_verify_zeroization(void *vdrbg)294{295PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;296PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)drbg->data;297int ret = 0;298299if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))300return 0;301302PROV_DRBG_VERIFY_ZEROIZATION(hmac->K);303PROV_DRBG_VERIFY_ZEROIZATION(hmac->V);304305ret = 1;306err:307if (drbg->lock != NULL)308CRYPTO_THREAD_unlock(drbg->lock);309return ret;310}311312static int drbg_hmac_new(PROV_DRBG *drbg)313{314PROV_DRBG_HMAC *hmac;315316hmac = OPENSSL_secure_zalloc(sizeof(*hmac));317if (hmac == NULL)318return 0;319320OSSL_FIPS_IND_INIT(drbg)321322drbg->data = hmac;323/* See SP800-57 Part1 Rev4 5.6.1 Table 3 */324drbg->max_entropylen = DRBG_MAX_LENGTH;325drbg->max_noncelen = DRBG_MAX_LENGTH;326drbg->max_perslen = DRBG_MAX_LENGTH;327drbg->max_adinlen = DRBG_MAX_LENGTH;328329/* Maximum number of bits per request = 2^19 = 2^16 bytes */330drbg->max_request = 1 << 16;331return 1;332}333334static void *drbg_hmac_new_wrapper(void *provctx, void *parent,335const OSSL_DISPATCH *parent_dispatch)336{337return ossl_rand_drbg_new(provctx, parent, parent_dispatch,338&drbg_hmac_new, &drbg_hmac_free,339&drbg_hmac_instantiate, &drbg_hmac_uninstantiate,340&drbg_hmac_reseed, &drbg_hmac_generate);341}342343static void drbg_hmac_free(void *vdrbg)344{345PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;346PROV_DRBG_HMAC *hmac;347348if (drbg != NULL && (hmac = (PROV_DRBG_HMAC *)drbg->data) != NULL) {349EVP_MAC_CTX_free(hmac->ctx);350ossl_prov_digest_reset(&hmac->digest);351OPENSSL_secure_clear_free(hmac, sizeof(*hmac));352}353ossl_rand_drbg_free(drbg);354}355356static int drbg_hmac_get_ctx_params(void *vdrbg, OSSL_PARAM params[])357{358PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;359PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)drbg->data;360const char *name;361const EVP_MD *md;362OSSL_PARAM *p;363int ret = 0, complete = 0;364365if (!ossl_drbg_get_ctx_params_no_lock(drbg, params, &complete))366return 0;367368if (complete)369return 1;370371if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))372return 0;373374p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_MAC);375if (p != NULL) {376if (hmac->ctx == NULL)377goto err;378name = EVP_MAC_get0_name(EVP_MAC_CTX_get0_mac(hmac->ctx));379if (!OSSL_PARAM_set_utf8_string(p, name))380goto err;381}382383p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_DIGEST);384if (p != NULL) {385md = ossl_prov_digest_md(&hmac->digest);386if (md == NULL || !OSSL_PARAM_set_utf8_string(p, EVP_MD_get0_name(md)))387goto err;388}389390ret = ossl_drbg_get_ctx_params(drbg, params);391err:392if (drbg->lock != NULL)393CRYPTO_THREAD_unlock(drbg->lock);394395return ret;396}397398static const OSSL_PARAM *drbg_hmac_gettable_ctx_params(ossl_unused void *vctx,399ossl_unused void *p_ctx)400{401static const OSSL_PARAM known_gettable_ctx_params[] = {402OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_MAC, NULL, 0),403OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_DIGEST, NULL, 0),404OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON,405OSSL_FIPS_IND_GETTABLE_CTX_PARAM()406OSSL_PARAM_END407};408return known_gettable_ctx_params;409}410411static int drbg_fetch_algs_from_prov(const OSSL_PARAM params[],412OSSL_LIB_CTX *libctx,413EVP_MAC_CTX **macctx,414EVP_MD **digest)415{416OSSL_PROVIDER *prov = NULL;417const OSSL_PARAM *p;418const char *digest_name = NULL;419const char *hmac_name = NULL;420EVP_MD *md = NULL;421EVP_MAC *mac = NULL;422OSSL_PARAM mac_params[2], *mp = mac_params;423int ret = 0;424425if (macctx == NULL || digest == NULL)426return 0;427428if ((p = OSSL_PARAM_locate_const(params,429OSSL_PROV_PARAM_CORE_PROV_NAME))430== NULL)431return 0;432if (p->data_type != OSSL_PARAM_UTF8_STRING)433return 0;434if ((prov = ossl_provider_find(libctx, (const char *)p->data, 1)) == NULL)435return 0;436437p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST);438if (p) {439if (OSSL_PARAM_get_utf8_string_ptr(p, &digest_name)) {440ERR_raise(ERR_LIB_PROV, PROV_R_VALUE_ERROR);441goto done;442}443md = evp_digest_fetch_from_prov(prov, digest_name, NULL);444if (md) {445EVP_MD_free(*digest);446*digest = md;447} else {448ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST);449goto done;450}451} else {452/* we need a digest */453ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST);454goto done;455}456p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_MAC);457if (p == NULL) {458hmac_name = "HMAC";459} else {460if (OSSL_PARAM_get_utf8_string_ptr(p, &hmac_name)) {461ERR_raise(ERR_LIB_PROV, PROV_R_VALUE_ERROR);462goto done;463}464}465466EVP_MAC_CTX_free(*macctx);467*macctx = NULL;468469mac = evp_mac_fetch_from_prov(prov, hmac_name, NULL);470if (mac) {471*macctx = EVP_MAC_CTX_new(mac);472/* The context holds on to the MAC */473EVP_MAC_free(mac);474*mp++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, (char *)digest_name, 0);475*mp = OSSL_PARAM_construct_end();476if (!EVP_MAC_CTX_set_params(*macctx, mac_params)) {477ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MAC);478EVP_MAC_CTX_free(*macctx);479*macctx = NULL;480goto done;481}482ret = 1;483}484485done:486ossl_provider_free(prov);487return ret;488}489490static int drbg_hmac_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[])491{492PROV_DRBG *ctx = (PROV_DRBG *)vctx;493PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)ctx->data;494OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);495EVP_MD *prov_md = NULL;496const EVP_MD *md;497int md_size;498499if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,500OSSL_DRBG_PARAM_FIPS_DIGEST_CHECK))501return 0;502503/* try to fetch mac and digest from provider */504(void)ERR_set_mark();505if (!drbg_fetch_algs_from_prov(params, libctx, &hmac->ctx, &prov_md)) {506(void)ERR_pop_to_mark();507/* fall back to full implementation search */508if (!ossl_prov_digest_load_from_params(&hmac->digest, params, libctx))509return 0;510511if (!ossl_prov_macctx_load_from_params(&hmac->ctx, params,512NULL, NULL, NULL, libctx))513return 0;514} else {515(void)ERR_clear_last_mark();516if (prov_md)517ossl_prov_digest_set_md(&hmac->digest, prov_md);518}519520md = ossl_prov_digest_md(&hmac->digest);521if (md != NULL && !ossl_drbg_verify_digest(ctx, libctx, md))522return 0; /* Error already raised for us */523524if (md != NULL && hmac->ctx != NULL) {525/* These are taken from SP 800-90 10.1 Table 2 */526md_size = EVP_MD_get_size(md);527if (md_size <= 0)528return 0;529hmac->blocklen = (size_t)md_size;530/* See SP800-57 Part1 Rev4 5.6.1 Table 3 */531ctx->strength = 64 * (int)(hmac->blocklen >> 3);532if (ctx->strength > 256)533ctx->strength = 256;534ctx->seedlen = hmac->blocklen;535ctx->min_entropylen = ctx->strength / 8;536ctx->min_noncelen = ctx->min_entropylen / 2;537}538539return ossl_drbg_set_ctx_params(ctx, params);540}541542static int drbg_hmac_set_ctx_params(void *vctx, const OSSL_PARAM params[])543{544PROV_DRBG *drbg = (PROV_DRBG *)vctx;545int ret;546547if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))548return 0;549550ret = drbg_hmac_set_ctx_params_locked(vctx, params);551552if (drbg->lock != NULL)553CRYPTO_THREAD_unlock(drbg->lock);554555return ret;556}557558static const OSSL_PARAM *drbg_hmac_settable_ctx_params(ossl_unused void *vctx,559ossl_unused void *p_ctx)560{561static const OSSL_PARAM known_settable_ctx_params[] = {562OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),563OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_DIGEST, NULL, 0),564OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_MAC, NULL, 0),565OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,566OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_DRBG_PARAM_FIPS_DIGEST_CHECK)567OSSL_PARAM_END568};569return known_settable_ctx_params;570}571572const OSSL_DISPATCH ossl_drbg_ossl_hmac_functions[] = {573{ OSSL_FUNC_RAND_NEWCTX, (void (*)(void))drbg_hmac_new_wrapper },574{ OSSL_FUNC_RAND_FREECTX, (void (*)(void))drbg_hmac_free },575{ OSSL_FUNC_RAND_INSTANTIATE,576(void (*)(void))drbg_hmac_instantiate_wrapper },577{ OSSL_FUNC_RAND_UNINSTANTIATE,578(void (*)(void))drbg_hmac_uninstantiate_wrapper },579{ OSSL_FUNC_RAND_GENERATE, (void (*)(void))drbg_hmac_generate_wrapper },580{ OSSL_FUNC_RAND_RESEED, (void (*)(void))drbg_hmac_reseed_wrapper },581{ OSSL_FUNC_RAND_ENABLE_LOCKING, (void (*)(void))ossl_drbg_enable_locking },582{ OSSL_FUNC_RAND_LOCK, (void (*)(void))ossl_drbg_lock },583{ OSSL_FUNC_RAND_UNLOCK, (void (*)(void))ossl_drbg_unlock },584{ OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS,585(void (*)(void))drbg_hmac_settable_ctx_params },586{ OSSL_FUNC_RAND_SET_CTX_PARAMS, (void (*)(void))drbg_hmac_set_ctx_params },587{ OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,588(void (*)(void))drbg_hmac_gettable_ctx_params },589{ OSSL_FUNC_RAND_GET_CTX_PARAMS, (void (*)(void))drbg_hmac_get_ctx_params },590{ OSSL_FUNC_RAND_VERIFY_ZEROIZATION,591(void (*)(void))drbg_hmac_verify_zeroization },592{ OSSL_FUNC_RAND_GET_SEED, (void (*)(void))ossl_drbg_get_seed },593{ OSSL_FUNC_RAND_CLEAR_SEED, (void (*)(void))ossl_drbg_clear_seed },594OSSL_DISPATCH_END595};596597598