evp_rand.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. /*
  2. * Copyright 2020 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 <openssl/evp.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <openssl/engine.h>
  13. #include <openssl/evp.h>
  14. #include <openssl/x509v3.h>
  15. #include <openssl/rand.h>
  16. #include <openssl/core.h>
  17. #include <openssl/core_names.h>
  18. #include <openssl/crypto.h>
  19. #include "crypto/asn1.h"
  20. #include "crypto/evp.h"
  21. #include "internal/cryptlib.h"
  22. #include "internal/numbers.h"
  23. #include "internal/provider.h"
  24. #include "evp_local.h"
  25. static int evp_rand_up_ref(void *vrand)
  26. {
  27. EVP_RAND *rand = (EVP_RAND *)vrand;
  28. int ref = 0;
  29. if (rand != NULL)
  30. return CRYPTO_UP_REF(&rand->refcnt, &ref, rand->refcnt_lock);
  31. return 1;
  32. }
  33. static void evp_rand_free(void *vrand){
  34. EVP_RAND *rand = (EVP_RAND *)vrand;
  35. int ref = 0;
  36. if (rand != NULL) {
  37. CRYPTO_DOWN_REF(&rand->refcnt, &ref, rand->refcnt_lock);
  38. if (ref <= 0) {
  39. ossl_provider_free(rand->prov);
  40. CRYPTO_THREAD_lock_free(rand->refcnt_lock);
  41. OPENSSL_free(rand);
  42. }
  43. }
  44. }
  45. static void *evp_rand_new(void)
  46. {
  47. EVP_RAND *rand = OPENSSL_zalloc(sizeof(*rand));
  48. if (rand == NULL
  49. || (rand->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL) {
  50. OPENSSL_free(rand);
  51. return NULL;
  52. }
  53. rand->refcnt = 1;
  54. return rand;
  55. }
  56. /* Enable locking of the underlying DRBG/RAND if available */
  57. int EVP_RAND_enable_locking(EVP_RAND_CTX *rand)
  58. {
  59. if (rand->meth->enable_locking != NULL)
  60. return rand->meth->enable_locking(rand->data);
  61. EVPerr(0, EVP_R_LOCKING_NOT_SUPPORTED);
  62. return 0;
  63. }
  64. /* Lock the underlying DRBG/RAND if available */
  65. static int evp_rand_lock(EVP_RAND_CTX *rand)
  66. {
  67. if (rand->meth->lock != NULL)
  68. return rand->meth->lock(rand->data);
  69. return 1;
  70. }
  71. /* Unlock the underlying DRBG/RAND if available */
  72. static void evp_rand_unlock(EVP_RAND_CTX *rand)
  73. {
  74. if (rand->meth->unlock != NULL)
  75. rand->meth->unlock(rand->data);
  76. }
  77. static void *evp_rand_from_dispatch(int name_id,
  78. const OSSL_DISPATCH *fns,
  79. OSSL_PROVIDER *prov)
  80. {
  81. EVP_RAND *rand = NULL;
  82. int fnrandcnt = 0, fnctxcnt = 0, fnlockcnt = 0;
  83. #ifdef FIPS_MODULE
  84. int fnzeroizecnt = 0;
  85. #endif
  86. if ((rand = evp_rand_new()) == NULL) {
  87. EVPerr(0, ERR_R_MALLOC_FAILURE);
  88. return NULL;
  89. }
  90. rand->name_id = name_id;
  91. rand->dispatch = fns;
  92. for (; fns->function_id != 0; fns++) {
  93. switch (fns->function_id) {
  94. case OSSL_FUNC_RAND_NEWCTX:
  95. if (rand->newctx != NULL)
  96. break;
  97. rand->newctx = OSSL_FUNC_rand_newctx(fns);
  98. fnctxcnt++;
  99. break;
  100. case OSSL_FUNC_RAND_FREECTX:
  101. if (rand->freectx != NULL)
  102. break;
  103. rand->freectx = OSSL_FUNC_rand_freectx(fns);
  104. fnctxcnt++;
  105. break;
  106. case OSSL_FUNC_RAND_INSTANTIATE:
  107. if (rand->instantiate != NULL)
  108. break;
  109. rand->instantiate = OSSL_FUNC_rand_instantiate(fns);
  110. fnrandcnt++;
  111. break;
  112. case OSSL_FUNC_RAND_UNINSTANTIATE:
  113. if (rand->uninstantiate != NULL)
  114. break;
  115. rand->uninstantiate = OSSL_FUNC_rand_uninstantiate(fns);
  116. fnrandcnt++;
  117. break;
  118. case OSSL_FUNC_RAND_GENERATE:
  119. if (rand->generate != NULL)
  120. break;
  121. rand->generate = OSSL_FUNC_rand_generate(fns);
  122. fnrandcnt++;
  123. break;
  124. case OSSL_FUNC_RAND_RESEED:
  125. if (rand->reseed != NULL)
  126. break;
  127. rand->reseed = OSSL_FUNC_rand_reseed(fns);
  128. break;
  129. case OSSL_FUNC_RAND_NONCE:
  130. if (rand->nonce != NULL)
  131. break;
  132. rand->nonce = OSSL_FUNC_rand_nonce(fns);
  133. break;
  134. case OSSL_FUNC_RAND_SET_CALLBACKS:
  135. if (rand->set_callbacks != NULL)
  136. break;
  137. rand->set_callbacks = OSSL_FUNC_rand_set_callbacks(fns);
  138. break;
  139. case OSSL_FUNC_RAND_ENABLE_LOCKING:
  140. if (rand->enable_locking != NULL)
  141. break;
  142. rand->enable_locking = OSSL_FUNC_rand_enable_locking(fns);
  143. fnlockcnt++;
  144. break;
  145. case OSSL_FUNC_RAND_LOCK:
  146. if (rand->lock != NULL)
  147. break;
  148. rand->lock = OSSL_FUNC_rand_lock(fns);
  149. fnlockcnt++;
  150. break;
  151. case OSSL_FUNC_RAND_UNLOCK:
  152. if (rand->unlock != NULL)
  153. break;
  154. rand->unlock = OSSL_FUNC_rand_unlock(fns);
  155. fnlockcnt++;
  156. break;
  157. case OSSL_FUNC_RAND_GETTABLE_PARAMS:
  158. if (rand->gettable_params != NULL)
  159. break;
  160. rand->gettable_params =
  161. OSSL_FUNC_rand_gettable_params(fns);
  162. break;
  163. case OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS:
  164. if (rand->gettable_ctx_params != NULL)
  165. break;
  166. rand->gettable_ctx_params =
  167. OSSL_FUNC_rand_gettable_ctx_params(fns);
  168. break;
  169. case OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS:
  170. if (rand->settable_ctx_params != NULL)
  171. break;
  172. rand->settable_ctx_params =
  173. OSSL_FUNC_rand_settable_ctx_params(fns);
  174. break;
  175. case OSSL_FUNC_RAND_GET_PARAMS:
  176. if (rand->get_params != NULL)
  177. break;
  178. rand->get_params = OSSL_FUNC_rand_get_params(fns);
  179. break;
  180. case OSSL_FUNC_RAND_GET_CTX_PARAMS:
  181. if (rand->get_ctx_params != NULL)
  182. break;
  183. rand->get_ctx_params = OSSL_FUNC_rand_get_ctx_params(fns);
  184. fnctxcnt++;
  185. break;
  186. case OSSL_FUNC_RAND_SET_CTX_PARAMS:
  187. if (rand->set_ctx_params != NULL)
  188. break;
  189. rand->set_ctx_params = OSSL_FUNC_rand_set_ctx_params(fns);
  190. break;
  191. case OSSL_FUNC_RAND_VERIFY_ZEROIZATION:
  192. if (rand->verify_zeroization != NULL)
  193. break;
  194. rand->verify_zeroization = OSSL_FUNC_rand_verify_zeroization(fns);
  195. #ifdef FIPS_MODULE
  196. fnzeroizecnt++;
  197. #endif
  198. break;
  199. }
  200. }
  201. /*
  202. * In order to be a consistent set of functions we must have at least
  203. * a complete set of "rand" functions and a complete set of context
  204. * management functions. In FIPS mode, we also require the zeroization
  205. * verification function.
  206. *
  207. * In addition, if locking can be enabled, we need a complete set of
  208. * locking functions.
  209. */
  210. if (fnrandcnt != 3
  211. || fnctxcnt != 3
  212. || (fnlockcnt != 0 && fnlockcnt != 3)
  213. #ifdef FIPS_MODULE
  214. || fnzeroizecnt != 1
  215. #endif
  216. ) {
  217. evp_rand_free(rand);
  218. ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
  219. return NULL;
  220. }
  221. if (prov != NULL && !ossl_provider_up_ref(prov)) {
  222. evp_rand_free(rand);
  223. ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
  224. return NULL;
  225. }
  226. rand->prov = prov;
  227. return rand;
  228. }
  229. EVP_RAND *EVP_RAND_fetch(OPENSSL_CTX *libctx, const char *algorithm,
  230. const char *properties)
  231. {
  232. return evp_generic_fetch(libctx, OSSL_OP_RAND, algorithm, properties,
  233. evp_rand_from_dispatch, evp_rand_up_ref,
  234. evp_rand_free);
  235. }
  236. int EVP_RAND_up_ref(EVP_RAND *rand)
  237. {
  238. return evp_rand_up_ref(rand);
  239. }
  240. void EVP_RAND_free(EVP_RAND *rand)
  241. {
  242. evp_rand_free(rand);
  243. }
  244. int EVP_RAND_number(const EVP_RAND *rand)
  245. {
  246. return rand->name_id;
  247. }
  248. const char *EVP_RAND_name(const EVP_RAND *rand)
  249. {
  250. return evp_first_name(rand->prov, rand->name_id);
  251. }
  252. int EVP_RAND_is_a(const EVP_RAND *rand, const char *name)
  253. {
  254. return evp_is_a(rand->prov, rand->name_id, NULL, name);
  255. }
  256. const OSSL_PROVIDER *EVP_RAND_provider(const EVP_RAND *rand)
  257. {
  258. return rand->prov;
  259. }
  260. int EVP_RAND_get_params(EVP_RAND *rand, OSSL_PARAM params[])
  261. {
  262. if (rand->get_params != NULL)
  263. return rand->get_params(params);
  264. return 1;
  265. }
  266. EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent)
  267. {
  268. EVP_RAND_CTX *ctx;
  269. void *parent_ctx = NULL;
  270. const OSSL_DISPATCH *parent_dispatch = NULL;
  271. if (rand == NULL) {
  272. EVPerr(0, EVP_R_INVALID_NULL_ALGORITHM);
  273. return NULL;
  274. }
  275. ctx = OPENSSL_zalloc(sizeof(*ctx));
  276. if (ctx == NULL) {
  277. EVPerr(0, ERR_R_MALLOC_FAILURE);
  278. return NULL;
  279. }
  280. if (parent != NULL) {
  281. if (!EVP_RAND_enable_locking(parent)) {
  282. EVPerr(0, EVP_R_UNABLE_TO_ENABLE_PARENT_LOCKING);
  283. OPENSSL_free(ctx);
  284. return NULL;
  285. }
  286. parent_ctx = parent->data;
  287. parent_dispatch = parent->meth->dispatch;
  288. }
  289. if ((ctx->data = rand->newctx(ossl_provider_ctx(rand->prov), parent_ctx,
  290. parent_dispatch)) == NULL
  291. || !EVP_RAND_up_ref(rand)) {
  292. EVPerr(0, ERR_R_MALLOC_FAILURE);
  293. rand->freectx(ctx->data);
  294. OPENSSL_free(ctx);
  295. return NULL;
  296. }
  297. ctx->meth = rand;
  298. return ctx;
  299. }
  300. void EVP_RAND_CTX_free(EVP_RAND_CTX *ctx)
  301. {
  302. if (ctx != NULL) {
  303. ctx->meth->freectx(ctx->data);
  304. ctx->data = NULL;
  305. EVP_RAND_free(ctx->meth);
  306. OPENSSL_free(ctx);
  307. }
  308. }
  309. EVP_RAND *EVP_RAND_CTX_rand(EVP_RAND_CTX *ctx)
  310. {
  311. return ctx->meth;
  312. }
  313. static int evp_rand_get_ctx_params_locked(EVP_RAND_CTX *ctx,
  314. OSSL_PARAM params[])
  315. {
  316. return ctx->meth->get_ctx_params(ctx->data, params);
  317. }
  318. int EVP_RAND_get_ctx_params(EVP_RAND_CTX *ctx, OSSL_PARAM params[])
  319. {
  320. int res;
  321. if (!evp_rand_lock(ctx))
  322. return 0;
  323. res = evp_rand_get_ctx_params_locked(ctx, params);
  324. evp_rand_unlock(ctx);
  325. return res;
  326. }
  327. static int evp_rand_set_ctx_params_locked(EVP_RAND_CTX *ctx,
  328. const OSSL_PARAM params[])
  329. {
  330. if (ctx->meth->set_ctx_params != NULL)
  331. return ctx->meth->set_ctx_params(ctx->data, params);
  332. return 1;
  333. }
  334. int EVP_RAND_set_ctx_params(EVP_RAND_CTX *ctx, const OSSL_PARAM params[])
  335. {
  336. int res;
  337. if (!evp_rand_lock(ctx))
  338. return 0;
  339. res = evp_rand_set_ctx_params_locked(ctx, params);
  340. evp_rand_unlock(ctx);
  341. return res;
  342. }
  343. const OSSL_PARAM *EVP_RAND_gettable_params(const EVP_RAND *rand)
  344. {
  345. return rand->gettable_params == NULL ? NULL : rand->gettable_params();
  346. }
  347. const OSSL_PARAM *EVP_RAND_gettable_ctx_params(const EVP_RAND *rand)
  348. {
  349. return rand->gettable_ctx_params == NULL ? NULL
  350. : rand->gettable_ctx_params();
  351. }
  352. const OSSL_PARAM *EVP_RAND_settable_ctx_params(const EVP_RAND *rand)
  353. {
  354. return rand->settable_ctx_params == NULL ? NULL
  355. : rand->settable_ctx_params();
  356. }
  357. void EVP_RAND_do_all_provided(OPENSSL_CTX *libctx,
  358. void (*fn)(EVP_RAND *rand, void *arg),
  359. void *arg)
  360. {
  361. evp_generic_do_all(libctx, OSSL_OP_RAND,
  362. (void (*)(void *, void *))fn, arg,
  363. evp_rand_from_dispatch, evp_rand_free);
  364. }
  365. void EVP_RAND_names_do_all(const EVP_RAND *rand,
  366. void (*fn)(const char *name, void *data),
  367. void *data)
  368. {
  369. if (rand->prov != NULL)
  370. evp_names_do_all(rand->prov, rand->name_id, fn, data);
  371. }
  372. static int evp_rand_instantiate_locked
  373. (EVP_RAND_CTX *ctx, unsigned int strength, int prediction_resistance,
  374. const unsigned char *pstr, size_t pstr_len)
  375. {
  376. return ctx->meth->instantiate(ctx->data, strength, prediction_resistance,
  377. pstr, pstr_len);
  378. }
  379. int EVP_RAND_instantiate(EVP_RAND_CTX *ctx, unsigned int strength,
  380. int prediction_resistance,
  381. const unsigned char *pstr, size_t pstr_len)
  382. {
  383. int res;
  384. if (!evp_rand_lock(ctx))
  385. return 0;
  386. res = evp_rand_instantiate_locked(ctx, strength, prediction_resistance,
  387. pstr, pstr_len);
  388. evp_rand_unlock(ctx);
  389. return res;
  390. }
  391. static int evp_rand_uninstantiate_locked(EVP_RAND_CTX *ctx)
  392. {
  393. return ctx->meth->uninstantiate(ctx->data);
  394. }
  395. int EVP_RAND_uninstantiate(EVP_RAND_CTX *ctx)
  396. {
  397. int res;
  398. if (!evp_rand_lock(ctx))
  399. return 0;
  400. res = evp_rand_uninstantiate_locked(ctx);
  401. evp_rand_unlock(ctx);
  402. return res;
  403. }
  404. static int evp_rand_generate_locked(EVP_RAND_CTX *ctx, unsigned char *out,
  405. size_t outlen, unsigned int strength,
  406. int prediction_resistance,
  407. const unsigned char *addin,
  408. size_t addin_len)
  409. {
  410. size_t chunk, max_request = 0;
  411. OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
  412. params[0] = OSSL_PARAM_construct_size_t(OSSL_DRBG_PARAM_MAX_REQUEST,
  413. &max_request);
  414. if (!evp_rand_get_ctx_params_locked(ctx, params)
  415. || max_request == 0) {
  416. EVPerr(0, EVP_R_UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE);
  417. return 0;
  418. }
  419. for (; outlen > 0; outlen -= chunk, out += chunk) {
  420. chunk = outlen > max_request ? max_request : outlen;
  421. if (!ctx->meth->generate(ctx->data, out, chunk, strength,
  422. prediction_resistance, addin, addin_len)) {
  423. EVPerr(0, EVP_R_GENERATE_ERROR);
  424. return 0;
  425. }
  426. /*
  427. * Prediction resistance is only relevant the first time around,
  428. * subsequently, the DRBG has already been properly reseeded.
  429. */
  430. prediction_resistance = 0;
  431. }
  432. return 1;
  433. }
  434. int EVP_RAND_generate(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen,
  435. unsigned int strength, int prediction_resistance,
  436. const unsigned char *addin, size_t addin_len)
  437. {
  438. int res;
  439. if (!evp_rand_lock(ctx))
  440. return 0;
  441. res = evp_rand_generate_locked(ctx, out, outlen, strength,
  442. prediction_resistance, addin, addin_len);
  443. evp_rand_unlock(ctx);
  444. return res;
  445. }
  446. static int evp_rand_reseed_locked(EVP_RAND_CTX *ctx, int prediction_resistance,
  447. const unsigned char *ent, size_t ent_len,
  448. const unsigned char *addin, size_t addin_len)
  449. {
  450. if (ctx->meth->reseed != NULL)
  451. return ctx->meth->reseed(ctx->data, prediction_resistance,
  452. ent, ent_len, addin, addin_len);
  453. return 1;
  454. }
  455. int EVP_RAND_reseed(EVP_RAND_CTX *ctx, int prediction_resistance,
  456. const unsigned char *ent, size_t ent_len,
  457. const unsigned char *addin, size_t addin_len)
  458. {
  459. int res;
  460. if (!evp_rand_lock(ctx))
  461. return 0;
  462. res = evp_rand_reseed_locked(ctx, prediction_resistance,
  463. ent, ent_len, addin, addin_len);
  464. evp_rand_unlock(ctx);
  465. return res;
  466. }
  467. static unsigned int evp_rand_strength_locked(EVP_RAND_CTX *ctx)
  468. {
  469. OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
  470. unsigned int strength = 0;
  471. params[0] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH, &strength);
  472. if (!evp_rand_get_ctx_params_locked(ctx, params))
  473. return 0;
  474. return strength;
  475. }
  476. unsigned int EVP_RAND_strength(EVP_RAND_CTX *ctx)
  477. {
  478. unsigned int res;
  479. if (!evp_rand_lock(ctx))
  480. return 0;
  481. res = evp_rand_strength_locked(ctx);
  482. evp_rand_unlock(ctx);
  483. return res;
  484. }
  485. static int evp_rand_nonce_locked(EVP_RAND_CTX *ctx, unsigned char *out,
  486. size_t outlen)
  487. {
  488. unsigned int str = evp_rand_strength_locked(ctx);
  489. if (ctx->meth->nonce == NULL)
  490. return 0;
  491. if (ctx->meth->nonce(ctx->data, out, str, outlen, outlen))
  492. return 1;
  493. return evp_rand_generate_locked(ctx, out, outlen, str, 0, NULL, 0);
  494. }
  495. int EVP_RAND_nonce(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen)
  496. {
  497. int res;
  498. if (!evp_rand_lock(ctx))
  499. return 0;
  500. res = evp_rand_nonce_locked(ctx, out, outlen);
  501. evp_rand_unlock(ctx);
  502. return res;
  503. }
  504. int EVP_RAND_state(EVP_RAND_CTX *ctx)
  505. {
  506. OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
  507. int state;
  508. params[0] = OSSL_PARAM_construct_int(OSSL_RAND_PARAM_STATE, &state);
  509. if (!EVP_RAND_get_ctx_params(ctx, params))
  510. state = EVP_RAND_STATE_ERROR;
  511. return state;
  512. }
  513. static int evp_rand_set_callbacks_locked(EVP_RAND_CTX *ctx,
  514. OSSL_INOUT_CALLBACK *get_entropy,
  515. OSSL_CALLBACK *cleanup_entropy,
  516. OSSL_INOUT_CALLBACK *get_nonce,
  517. OSSL_CALLBACK *cleanup_nonce,
  518. void *arg)
  519. {
  520. if (ctx->meth->set_callbacks == NULL) {
  521. EVPerr(0, EVP_R_UNABLE_TO_SET_CALLBACKS);
  522. return 0;
  523. }
  524. ctx->meth->set_callbacks(ctx->data, get_entropy, cleanup_entropy,
  525. get_nonce, cleanup_nonce, arg);
  526. return 1;
  527. }
  528. int EVP_RAND_set_callbacks(EVP_RAND_CTX *ctx,
  529. OSSL_INOUT_CALLBACK *get_entropy,
  530. OSSL_CALLBACK *cleanup_entropy,
  531. OSSL_INOUT_CALLBACK *get_nonce,
  532. OSSL_CALLBACK *cleanup_nonce, void *arg)
  533. {
  534. int res;
  535. if (!evp_rand_lock(ctx))
  536. return 0;
  537. res = evp_rand_set_callbacks_locked(ctx, get_entropy, cleanup_entropy,
  538. get_nonce, cleanup_nonce, arg);
  539. evp_rand_unlock(ctx);
  540. return res;
  541. }
  542. static int evp_rand_verify_zeroization_locked(EVP_RAND_CTX *ctx)
  543. {
  544. if (ctx->meth->verify_zeroization != NULL)
  545. return ctx->meth->verify_zeroization(ctx->data);
  546. return 0;
  547. }
  548. int EVP_RAND_verify_zeroization(EVP_RAND_CTX *ctx)
  549. {
  550. int res;
  551. if (!evp_rand_lock(ctx))
  552. return 0;
  553. res = evp_rand_verify_zeroization_locked(ctx);
  554. evp_rand_unlock(ctx);
  555. return res;
  556. }