drbg_hmac.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. /*
  2. * Copyright 2011-2025 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #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"
  24. static OSSL_FUNC_rand_newctx_fn drbg_hmac_new_wrapper;
  25. static OSSL_FUNC_rand_freectx_fn drbg_hmac_free;
  26. static OSSL_FUNC_rand_instantiate_fn drbg_hmac_instantiate_wrapper;
  27. static OSSL_FUNC_rand_uninstantiate_fn drbg_hmac_uninstantiate_wrapper;
  28. static OSSL_FUNC_rand_generate_fn drbg_hmac_generate_wrapper;
  29. static OSSL_FUNC_rand_reseed_fn drbg_hmac_reseed_wrapper;
  30. static OSSL_FUNC_rand_settable_ctx_params_fn drbg_hmac_settable_ctx_params;
  31. static OSSL_FUNC_rand_set_ctx_params_fn drbg_hmac_set_ctx_params;
  32. static OSSL_FUNC_rand_gettable_ctx_params_fn drbg_hmac_gettable_ctx_params;
  33. static OSSL_FUNC_rand_get_ctx_params_fn drbg_hmac_get_ctx_params;
  34. static OSSL_FUNC_rand_verify_zeroization_fn drbg_hmac_verify_zeroization;
  35. static int drbg_hmac_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[]);
  36. /*
  37. * Called twice by SP800-90Ar1 10.1.2.2 HMAC_DRBG_Update_Process.
  38. *
  39. * hmac is an object that holds the input/output Key and Value (K and V).
  40. * inbyte is 0x00 on the first call and 0x01 on the second call.
  41. * in1, in2, in3 are optional inputs that can be NULL.
  42. * in1len, in2len, in3len are the lengths of the input buffers.
  43. *
  44. * The returned K,V is:
  45. * hmac->K = HMAC(hmac->K, hmac->V || inbyte || [in1] || [in2] || [in3])
  46. * hmac->V = HMAC(hmac->K, hmac->V)
  47. *
  48. * Returns zero if an error occurs otherwise it returns 1.
  49. */
  50. static int do_hmac(PROV_DRBG_HMAC *hmac, unsigned char inbyte,
  51. const unsigned char *in1, size_t in1len,
  52. const unsigned char *in2, size_t in2len,
  53. const unsigned char *in3, size_t in3len)
  54. {
  55. EVP_MAC_CTX *ctx = hmac->ctx;
  56. if (!EVP_MAC_init(ctx, hmac->K, hmac->blocklen, NULL)
  57. /* K = HMAC(K, V || inbyte || [in1] || [in2] || [in3]) */
  58. || !EVP_MAC_update(ctx, hmac->V, hmac->blocklen)
  59. || !EVP_MAC_update(ctx, &inbyte, 1)
  60. || !(in1 == NULL || in1len == 0 || EVP_MAC_update(ctx, in1, in1len))
  61. || !(in2 == NULL || in2len == 0 || EVP_MAC_update(ctx, in2, in2len))
  62. || !(in3 == NULL || in3len == 0 || EVP_MAC_update(ctx, in3, in3len))
  63. || !EVP_MAC_final(ctx, hmac->K, NULL, sizeof(hmac->K)))
  64. return 0;
  65. /* V = HMAC(K, V) */
  66. return EVP_MAC_init(ctx, hmac->K, hmac->blocklen, NULL)
  67. && EVP_MAC_update(ctx, hmac->V, hmac->blocklen)
  68. && EVP_MAC_final(ctx, hmac->V, NULL, sizeof(hmac->V));
  69. }
  70. /*
  71. * SP800-90Ar1 10.1.2.2 HMAC_DRBG_Update_Process
  72. *
  73. *
  74. * Updates the drbg objects Key(K) and Value(V) using the following algorithm:
  75. * K,V = do_hmac(hmac, 0, in1, in2, in3)
  76. * if (any input is not NULL)
  77. * K,V = do_hmac(hmac, 1, in1, in2, in3)
  78. *
  79. * where in1, in2, in3 are optional input buffers that can be NULL.
  80. * in1len, in2len, in3len are the lengths of the input buffers.
  81. *
  82. * Returns zero if an error occurs otherwise it returns 1.
  83. */
  84. static int drbg_hmac_update(PROV_DRBG_HMAC *hmac,
  85. const unsigned char *in1, size_t in1len,
  86. const unsigned char *in2, size_t in2len,
  87. const unsigned char *in3, size_t in3len)
  88. {
  89. /* (Steps 1-2) K = HMAC(K, V||0x00||provided_data). V = HMAC(K,V) */
  90. if (!do_hmac(hmac, 0x00, in1, in1len, in2, in2len, in3, in3len))
  91. return 0;
  92. /* (Step 3) If provided_data == NULL then return (K,V) */
  93. if (in1len == 0 && in2len == 0 && in3len == 0)
  94. return 1;
  95. /* (Steps 4-5) K = HMAC(K, V||0x01||provided_data). V = HMAC(K,V) */
  96. return do_hmac(hmac, 0x01, in1, in1len, in2, in2len, in3, in3len);
  97. }
  98. /*
  99. * SP800-90Ar1 10.1.2.3 HMAC_DRBG_Instantiate_Process:
  100. *
  101. * This sets the drbg Key (K) to all zeros, and Value (V) to all 1's.
  102. * and then calls (K,V) = drbg_hmac_update() with input parameters:
  103. * ent = entropy data (Can be NULL) of length ent_len.
  104. * nonce = nonce data (Can be NULL) of length nonce_len.
  105. * pstr = personalization data (Can be NULL) of length pstr_len.
  106. *
  107. * Returns zero if an error occurs otherwise it returns 1.
  108. */
  109. int ossl_drbg_hmac_init(PROV_DRBG_HMAC *hmac,
  110. const unsigned char *ent, size_t ent_len,
  111. const unsigned char *nonce, size_t nonce_len,
  112. const unsigned char *pstr, size_t pstr_len)
  113. {
  114. if (hmac->ctx == NULL) {
  115. ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MAC);
  116. return 0;
  117. }
  118. /* (Step 2) Key = 0x00 00...00 */
  119. memset(hmac->K, 0x00, hmac->blocklen);
  120. /* (Step 3) V = 0x01 01...01 */
  121. memset(hmac->V, 0x01, hmac->blocklen);
  122. /* (Step 4) (K,V) = HMAC_DRBG_Update(entropy||nonce||pers string, K, V) */
  123. return drbg_hmac_update(hmac, ent, ent_len, nonce, nonce_len, pstr,
  124. pstr_len);
  125. }
  126. static int drbg_hmac_instantiate(PROV_DRBG *drbg,
  127. const unsigned char *ent, size_t ent_len,
  128. const unsigned char *nonce, size_t nonce_len,
  129. const unsigned char *pstr, size_t pstr_len)
  130. {
  131. return ossl_drbg_hmac_init((PROV_DRBG_HMAC *)drbg->data, ent, ent_len,
  132. nonce, nonce_len, pstr, pstr_len);
  133. }
  134. static int drbg_hmac_instantiate_wrapper(void *vdrbg, unsigned int strength,
  135. int prediction_resistance,
  136. const unsigned char *pstr,
  137. size_t pstr_len,
  138. const OSSL_PARAM params[])
  139. {
  140. PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
  141. int ret = 0;
  142. if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
  143. return 0;
  144. if (!ossl_prov_is_running()
  145. || !drbg_hmac_set_ctx_params_locked(drbg, params))
  146. goto err;
  147. ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
  148. pstr, pstr_len);
  149. err:
  150. if (drbg->lock != NULL)
  151. CRYPTO_THREAD_unlock(drbg->lock);
  152. return ret;
  153. }
  154. /*
  155. * SP800-90Ar1 10.1.2.4 HMAC_DRBG_Reseed_Process:
  156. *
  157. * Reseeds the drbg's Key (K) and Value (V) by calling
  158. * (K,V) = drbg_hmac_update() with the following input parameters:
  159. * ent = entropy input data (Can be NULL) of length ent_len.
  160. * adin = additional input data (Can be NULL) of length adin_len.
  161. *
  162. * Returns zero if an error occurs otherwise it returns 1.
  163. */
  164. static int drbg_hmac_reseed(PROV_DRBG *drbg,
  165. const unsigned char *ent, size_t ent_len,
  166. const unsigned char *adin, size_t adin_len)
  167. {
  168. PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)drbg->data;
  169. /* (Step 2) (K,V) = HMAC_DRBG_Update(entropy||additional_input, K, V) */
  170. return drbg_hmac_update(hmac, ent, ent_len, adin, adin_len, NULL, 0);
  171. }
  172. static int drbg_hmac_reseed_wrapper(void *vdrbg, int prediction_resistance,
  173. const unsigned char *ent, size_t ent_len,
  174. const unsigned char *adin, size_t adin_len)
  175. {
  176. PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
  177. return ossl_prov_drbg_reseed(drbg, prediction_resistance, ent, ent_len,
  178. adin, adin_len);
  179. }
  180. /*
  181. * SP800-90Ar1 10.1.2.5 HMAC_DRBG_Generate_Process:
  182. *
  183. * Generates pseudo random bytes and updates the internal K,V for the drbg.
  184. * out is a buffer to fill with outlen bytes of pseudo random data.
  185. * adin is an additional_input string of size adin_len that may be NULL.
  186. *
  187. * Returns zero if an error occurs otherwise it returns 1.
  188. */
  189. int ossl_drbg_hmac_generate(PROV_DRBG_HMAC *hmac,
  190. unsigned char *out, size_t outlen,
  191. const unsigned char *adin, size_t adin_len)
  192. {
  193. EVP_MAC_CTX *ctx = hmac->ctx;
  194. const unsigned char *temp = hmac->V;
  195. /* (Step 2) if adin != NULL then (K,V) = HMAC_DRBG_Update(adin, K, V) */
  196. if (adin != NULL
  197. && adin_len > 0
  198. && !drbg_hmac_update(hmac, adin, adin_len, NULL, 0, NULL, 0))
  199. return 0;
  200. /*
  201. * (Steps 3-5) temp = NULL
  202. * while (len(temp) < outlen) {
  203. * V = HMAC(K, V)
  204. * temp = temp || V
  205. * }
  206. */
  207. for (;;) {
  208. if (!EVP_MAC_init(ctx, hmac->K, hmac->blocklen, NULL)
  209. || !EVP_MAC_update(ctx, temp, hmac->blocklen))
  210. return 0;
  211. if (outlen > hmac->blocklen) {
  212. if (!EVP_MAC_final(ctx, out, NULL, outlen))
  213. return 0;
  214. temp = out;
  215. } else {
  216. if (!EVP_MAC_final(ctx, hmac->V, NULL, sizeof(hmac->V)))
  217. return 0;
  218. memcpy(out, hmac->V, outlen);
  219. break;
  220. }
  221. out += hmac->blocklen;
  222. outlen -= hmac->blocklen;
  223. }
  224. /* (Step 6) (K,V) = HMAC_DRBG_Update(adin, K, V) */
  225. if (!drbg_hmac_update(hmac, adin, adin_len, NULL, 0, NULL, 0))
  226. return 0;
  227. return 1;
  228. }
  229. static int drbg_hmac_generate(PROV_DRBG *drbg,
  230. unsigned char *out, size_t outlen,
  231. const unsigned char *adin, size_t adin_len)
  232. {
  233. return ossl_drbg_hmac_generate((PROV_DRBG_HMAC *)drbg->data, out, outlen,
  234. adin, adin_len);
  235. }
  236. static int drbg_hmac_generate_wrapper(void *vdrbg,
  237. unsigned char *out, size_t outlen, unsigned int strength,
  238. int prediction_resistance, const unsigned char *adin, size_t adin_len)
  239. {
  240. PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
  241. return ossl_prov_drbg_generate(drbg, out, outlen, strength,
  242. prediction_resistance, adin, adin_len);
  243. }
  244. static int drbg_hmac_uninstantiate(PROV_DRBG *drbg)
  245. {
  246. PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)drbg->data;
  247. OPENSSL_cleanse(hmac->K, sizeof(hmac->K));
  248. OPENSSL_cleanse(hmac->V, sizeof(hmac->V));
  249. return ossl_prov_drbg_uninstantiate(drbg);
  250. }
  251. static int drbg_hmac_uninstantiate_wrapper(void *vdrbg)
  252. {
  253. PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
  254. int ret;
  255. if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
  256. return 0;
  257. ret = drbg_hmac_uninstantiate(drbg);
  258. if (drbg->lock != NULL)
  259. CRYPTO_THREAD_unlock(drbg->lock);
  260. return ret;
  261. }
  262. static int drbg_hmac_verify_zeroization(void *vdrbg)
  263. {
  264. PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
  265. PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)drbg->data;
  266. int ret = 0;
  267. if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
  268. return 0;
  269. PROV_DRBG_VERIFY_ZEROIZATION(hmac->K);
  270. PROV_DRBG_VERIFY_ZEROIZATION(hmac->V);
  271. ret = 1;
  272. err:
  273. if (drbg->lock != NULL)
  274. CRYPTO_THREAD_unlock(drbg->lock);
  275. return ret;
  276. }
  277. static int drbg_hmac_new(PROV_DRBG *drbg)
  278. {
  279. PROV_DRBG_HMAC *hmac;
  280. hmac = OPENSSL_secure_zalloc(sizeof(*hmac));
  281. if (hmac == NULL)
  282. return 0;
  283. OSSL_FIPS_IND_INIT(drbg)
  284. drbg->data = hmac;
  285. /* See SP800-57 Part1 Rev4 5.6.1 Table 3 */
  286. drbg->max_entropylen = DRBG_MAX_LENGTH;
  287. drbg->max_noncelen = DRBG_MAX_LENGTH;
  288. drbg->max_perslen = DRBG_MAX_LENGTH;
  289. drbg->max_adinlen = DRBG_MAX_LENGTH;
  290. /* Maximum number of bits per request = 2^19 = 2^16 bytes */
  291. drbg->max_request = 1 << 16;
  292. return 1;
  293. }
  294. static void *drbg_hmac_new_wrapper(void *provctx, void *parent,
  295. const OSSL_DISPATCH *parent_dispatch)
  296. {
  297. return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
  298. &drbg_hmac_new, &drbg_hmac_free,
  299. &drbg_hmac_instantiate, &drbg_hmac_uninstantiate,
  300. &drbg_hmac_reseed, &drbg_hmac_generate);
  301. }
  302. static void drbg_hmac_free(void *vdrbg)
  303. {
  304. PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
  305. PROV_DRBG_HMAC *hmac;
  306. if (drbg != NULL && (hmac = (PROV_DRBG_HMAC *)drbg->data) != NULL) {
  307. EVP_MAC_CTX_free(hmac->ctx);
  308. ossl_prov_digest_reset(&hmac->digest);
  309. OPENSSL_secure_clear_free(hmac, sizeof(*hmac));
  310. }
  311. ossl_rand_drbg_free(drbg);
  312. }
  313. static int drbg_hmac_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
  314. {
  315. PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
  316. PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)drbg->data;
  317. const char *name;
  318. const EVP_MD *md;
  319. OSSL_PARAM *p;
  320. int ret = 0, complete = 0;
  321. if (!ossl_drbg_get_ctx_params_no_lock(drbg, params, &complete))
  322. return 0;
  323. if (complete)
  324. return 1;
  325. if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
  326. return 0;
  327. p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_MAC);
  328. if (p != NULL) {
  329. if (hmac->ctx == NULL)
  330. goto err;
  331. name = EVP_MAC_get0_name(EVP_MAC_CTX_get0_mac(hmac->ctx));
  332. if (!OSSL_PARAM_set_utf8_string(p, name))
  333. goto err;
  334. }
  335. p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_DIGEST);
  336. if (p != NULL) {
  337. md = ossl_prov_digest_md(&hmac->digest);
  338. if (md == NULL || !OSSL_PARAM_set_utf8_string(p, EVP_MD_get0_name(md)))
  339. goto err;
  340. }
  341. ret = ossl_drbg_get_ctx_params(drbg, params);
  342. err:
  343. if (drbg->lock != NULL)
  344. CRYPTO_THREAD_unlock(drbg->lock);
  345. return ret;
  346. }
  347. static const OSSL_PARAM *drbg_hmac_gettable_ctx_params(ossl_unused void *vctx,
  348. ossl_unused void *p_ctx)
  349. {
  350. static const OSSL_PARAM known_gettable_ctx_params[] = {
  351. OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_MAC, NULL, 0),
  352. OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_DIGEST, NULL, 0),
  353. OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON,
  354. OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
  355. OSSL_PARAM_END
  356. };
  357. return known_gettable_ctx_params;
  358. }
  359. static int drbg_fetch_algs_from_prov(const OSSL_PARAM params[],
  360. OSSL_LIB_CTX *libctx,
  361. EVP_MAC_CTX **macctx,
  362. EVP_MD **digest)
  363. {
  364. OSSL_PROVIDER *prov = NULL;
  365. const OSSL_PARAM *p;
  366. EVP_MD *md = NULL;
  367. EVP_MAC *mac = NULL;
  368. int ret = 0;
  369. if (macctx == NULL || digest == NULL)
  370. return 0;
  371. if ((p = OSSL_PARAM_locate_const(params,
  372. OSSL_PROV_PARAM_CORE_PROV_NAME)) == NULL)
  373. return 0;
  374. if (p->data_type != OSSL_PARAM_UTF8_STRING)
  375. return 0;
  376. if ((prov = ossl_provider_find(libctx, (const char *)p->data, 1)) == NULL)
  377. return 0;
  378. p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST);
  379. if (p) {
  380. if (p->data_type != OSSL_PARAM_UTF8_STRING)
  381. goto done;
  382. md = evp_digest_fetch_from_prov(prov, (const char *)p->data, NULL);
  383. if (md) {
  384. EVP_MD_free(*digest);
  385. *digest = md;
  386. } else {
  387. goto done;
  388. }
  389. }
  390. p = OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_MAC);
  391. if (p == NULL) {
  392. ret = 1;
  393. goto done;
  394. }
  395. if (p->data_type != OSSL_PARAM_UTF8_STRING)
  396. goto done;
  397. EVP_MAC_CTX_free(*macctx);
  398. *macctx = NULL;
  399. mac = evp_mac_fetch_from_prov(prov, (const char *)p->data, NULL);
  400. if (mac) {
  401. *macctx = EVP_MAC_CTX_new(mac);
  402. /* The context holds on to the MAC */
  403. EVP_MAC_free(mac);
  404. ret = 1;
  405. }
  406. done:
  407. ossl_provider_free(prov);
  408. return ret;
  409. }
  410. static int drbg_hmac_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[])
  411. {
  412. PROV_DRBG *ctx = (PROV_DRBG *)vctx;
  413. PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)ctx->data;
  414. OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
  415. EVP_MD *prov_md = NULL;
  416. const EVP_MD *md;
  417. int md_size;
  418. if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,
  419. OSSL_DRBG_PARAM_FIPS_DIGEST_CHECK))
  420. return 0;
  421. /* try to fetch mac and digest from provider */
  422. (void)ERR_set_mark();
  423. if (!drbg_fetch_algs_from_prov(params, libctx, &hmac->ctx, &prov_md)) {
  424. (void)ERR_pop_to_mark();
  425. /* fall back to full implementation search */
  426. if (!ossl_prov_digest_load_from_params(&hmac->digest, params, libctx))
  427. return 0;
  428. if (!ossl_prov_macctx_load_from_params(&hmac->ctx, params,
  429. NULL, NULL, NULL, libctx))
  430. return 0;
  431. } else {
  432. (void)ERR_clear_last_mark();
  433. if (prov_md)
  434. ossl_prov_digest_set_md(&hmac->digest, prov_md);
  435. }
  436. md = ossl_prov_digest_md(&hmac->digest);
  437. if (md != NULL && !ossl_drbg_verify_digest(ctx, libctx, md))
  438. return 0; /* Error already raised for us */
  439. if (md != NULL && hmac->ctx != NULL) {
  440. /* These are taken from SP 800-90 10.1 Table 2 */
  441. md_size = EVP_MD_get_size(md);
  442. if (md_size <= 0)
  443. return 0;
  444. hmac->blocklen = (size_t)md_size;
  445. /* See SP800-57 Part1 Rev4 5.6.1 Table 3 */
  446. ctx->strength = 64 * (int)(hmac->blocklen >> 3);
  447. if (ctx->strength > 256)
  448. ctx->strength = 256;
  449. ctx->seedlen = hmac->blocklen;
  450. ctx->min_entropylen = ctx->strength / 8;
  451. ctx->min_noncelen = ctx->min_entropylen / 2;
  452. }
  453. return ossl_drbg_set_ctx_params(ctx, params);
  454. }
  455. static int drbg_hmac_set_ctx_params(void *vctx, const OSSL_PARAM params[])
  456. {
  457. PROV_DRBG *drbg = (PROV_DRBG *)vctx;
  458. int ret;
  459. if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
  460. return 0;
  461. ret = drbg_hmac_set_ctx_params_locked(vctx, params);
  462. if (drbg->lock != NULL)
  463. CRYPTO_THREAD_unlock(drbg->lock);
  464. return ret;
  465. }
  466. static const OSSL_PARAM *drbg_hmac_settable_ctx_params(ossl_unused void *vctx,
  467. ossl_unused void *p_ctx)
  468. {
  469. static const OSSL_PARAM known_settable_ctx_params[] = {
  470. OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
  471. OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_DIGEST, NULL, 0),
  472. OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_MAC, NULL, 0),
  473. OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
  474. OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_DRBG_PARAM_FIPS_DIGEST_CHECK)
  475. OSSL_PARAM_END
  476. };
  477. return known_settable_ctx_params;
  478. }
  479. const OSSL_DISPATCH ossl_drbg_ossl_hmac_functions[] = {
  480. { OSSL_FUNC_RAND_NEWCTX, (void(*)(void))drbg_hmac_new_wrapper },
  481. { OSSL_FUNC_RAND_FREECTX, (void(*)(void))drbg_hmac_free },
  482. { OSSL_FUNC_RAND_INSTANTIATE,
  483. (void(*)(void))drbg_hmac_instantiate_wrapper },
  484. { OSSL_FUNC_RAND_UNINSTANTIATE,
  485. (void(*)(void))drbg_hmac_uninstantiate_wrapper },
  486. { OSSL_FUNC_RAND_GENERATE, (void(*)(void))drbg_hmac_generate_wrapper },
  487. { OSSL_FUNC_RAND_RESEED, (void(*)(void))drbg_hmac_reseed_wrapper },
  488. { OSSL_FUNC_RAND_ENABLE_LOCKING, (void(*)(void))ossl_drbg_enable_locking },
  489. { OSSL_FUNC_RAND_LOCK, (void(*)(void))ossl_drbg_lock },
  490. { OSSL_FUNC_RAND_UNLOCK, (void(*)(void))ossl_drbg_unlock },
  491. { OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS,
  492. (void(*)(void))drbg_hmac_settable_ctx_params },
  493. { OSSL_FUNC_RAND_SET_CTX_PARAMS, (void(*)(void))drbg_hmac_set_ctx_params },
  494. { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
  495. (void(*)(void))drbg_hmac_gettable_ctx_params },
  496. { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))drbg_hmac_get_ctx_params },
  497. { OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
  498. (void(*)(void))drbg_hmac_verify_zeroization },
  499. { OSSL_FUNC_RAND_GET_SEED, (void(*)(void))ossl_drbg_get_seed },
  500. { OSSL_FUNC_RAND_CLEAR_SEED, (void(*)(void))ossl_drbg_clear_seed },
  501. OSSL_DISPATCH_END
  502. };