]>
Commit | Line | Data |
---|---|---|
15dfa092 | 1 | /* |
4333b89f | 2 | * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. |
15dfa092 P |
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 | ||
15dfa092 P |
10 | #include <stdio.h> |
11 | #include <stdlib.h> | |
15dfa092 | 12 | #include <openssl/evp.h> |
15dfa092 P |
13 | #include <openssl/rand.h> |
14 | #include <openssl/core.h> | |
15 | #include <openssl/core_names.h> | |
16 | #include <openssl/crypto.h> | |
f000e828 | 17 | #include "internal/cryptlib.h" |
15dfa092 P |
18 | #include "internal/numbers.h" |
19 | #include "internal/provider.h" | |
6c9bc258 | 20 | #include "internal/core.h" |
6c9bc258 | 21 | #include "crypto/evp.h" |
15dfa092 P |
22 | #include "evp_local.h" |
23 | ||
7d615e21 P |
24 | struct evp_rand_st { |
25 | OSSL_PROVIDER *prov; | |
26 | int name_id; | |
6c9bc258 | 27 | char *type_name; |
309a78aa | 28 | const char *description; |
7d615e21 P |
29 | CRYPTO_REF_COUNT refcnt; |
30 | CRYPTO_RWLOCK *refcnt_lock; | |
31 | ||
32 | const OSSL_DISPATCH *dispatch; | |
33 | OSSL_FUNC_rand_newctx_fn *newctx; | |
34 | OSSL_FUNC_rand_freectx_fn *freectx; | |
35 | OSSL_FUNC_rand_instantiate_fn *instantiate; | |
36 | OSSL_FUNC_rand_uninstantiate_fn *uninstantiate; | |
37 | OSSL_FUNC_rand_generate_fn *generate; | |
38 | OSSL_FUNC_rand_reseed_fn *reseed; | |
39 | OSSL_FUNC_rand_nonce_fn *nonce; | |
40 | OSSL_FUNC_rand_enable_locking_fn *enable_locking; | |
41 | OSSL_FUNC_rand_lock_fn *lock; | |
42 | OSSL_FUNC_rand_unlock_fn *unlock; | |
43 | OSSL_FUNC_rand_gettable_params_fn *gettable_params; | |
44 | OSSL_FUNC_rand_gettable_ctx_params_fn *gettable_ctx_params; | |
45 | OSSL_FUNC_rand_settable_ctx_params_fn *settable_ctx_params; | |
46 | OSSL_FUNC_rand_get_params_fn *get_params; | |
47 | OSSL_FUNC_rand_get_ctx_params_fn *get_ctx_params; | |
48 | OSSL_FUNC_rand_set_ctx_params_fn *set_ctx_params; | |
49 | OSSL_FUNC_rand_verify_zeroization_fn *verify_zeroization; | |
50 | } /* EVP_RAND */ ; | |
51 | ||
15dfa092 P |
52 | static int evp_rand_up_ref(void *vrand) |
53 | { | |
54 | EVP_RAND *rand = (EVP_RAND *)vrand; | |
55 | int ref = 0; | |
56 | ||
57 | if (rand != NULL) | |
f000e828 | 58 | return CRYPTO_UP_REF(&rand->refcnt, &ref, rand->refcnt_lock); |
15dfa092 P |
59 | return 1; |
60 | } | |
61 | ||
543e740b RS |
62 | static void evp_rand_free(void *vrand) |
63 | { | |
15dfa092 P |
64 | EVP_RAND *rand = (EVP_RAND *)vrand; |
65 | int ref = 0; | |
66 | ||
543e740b RS |
67 | if (rand == NULL) |
68 | return; | |
69 | CRYPTO_DOWN_REF(&rand->refcnt, &ref, rand->refcnt_lock); | |
70 | if (ref > 0) | |
71 | return; | |
6c9bc258 | 72 | OPENSSL_free(rand->type_name); |
543e740b RS |
73 | ossl_provider_free(rand->prov); |
74 | CRYPTO_THREAD_lock_free(rand->refcnt_lock); | |
75 | OPENSSL_free(rand); | |
15dfa092 P |
76 | } |
77 | ||
78 | static void *evp_rand_new(void) | |
79 | { | |
f000e828 | 80 | EVP_RAND *rand = OPENSSL_zalloc(sizeof(*rand)); |
15dfa092 | 81 | |
f000e828 P |
82 | if (rand == NULL |
83 | || (rand->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL) { | |
84 | OPENSSL_free(rand); | |
15dfa092 P |
85 | return NULL; |
86 | } | |
15dfa092 | 87 | rand->refcnt = 1; |
15dfa092 P |
88 | return rand; |
89 | } | |
90 | ||
714a1bb3 | 91 | /* Enable locking of the underlying DRBG/RAND if available */ |
f000e828 | 92 | int EVP_RAND_enable_locking(EVP_RAND_CTX *rand) |
714a1bb3 | 93 | { |
f000e828 | 94 | if (rand->meth->enable_locking != NULL) |
7c14d0c1 | 95 | return rand->meth->enable_locking(rand->algctx); |
9311d0c4 | 96 | ERR_raise(ERR_LIB_EVP, EVP_R_LOCKING_NOT_SUPPORTED); |
f000e828 | 97 | return 0; |
714a1bb3 P |
98 | } |
99 | ||
100 | /* Lock the underlying DRBG/RAND if available */ | |
101 | static int evp_rand_lock(EVP_RAND_CTX *rand) | |
102 | { | |
f000e828 | 103 | if (rand->meth->lock != NULL) |
7c14d0c1 | 104 | return rand->meth->lock(rand->algctx); |
714a1bb3 P |
105 | return 1; |
106 | } | |
107 | ||
108 | /* Unlock the underlying DRBG/RAND if available */ | |
109 | static void evp_rand_unlock(EVP_RAND_CTX *rand) | |
110 | { | |
f000e828 | 111 | if (rand->meth->unlock != NULL) |
7c14d0c1 | 112 | rand->meth->unlock(rand->algctx); |
714a1bb3 P |
113 | } |
114 | ||
309a78aa RL |
115 | static void *evp_rand_from_algorithm(int name_id, |
116 | const OSSL_ALGORITHM *algodef, | |
117 | OSSL_PROVIDER *prov) | |
15dfa092 | 118 | { |
309a78aa | 119 | const OSSL_DISPATCH *fns = algodef->implementation; |
15dfa092 | 120 | EVP_RAND *rand = NULL; |
f626c3ff | 121 | int fnrandcnt = 0, fnctxcnt = 0, fnlockcnt = 0, fnenablelockcnt = 0; |
714a1bb3 | 122 | #ifdef FIPS_MODULE |
f000e828 | 123 | int fnzeroizecnt = 0; |
714a1bb3 | 124 | #endif |
15dfa092 P |
125 | |
126 | if ((rand = evp_rand_new()) == NULL) { | |
9311d0c4 | 127 | ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); |
15dfa092 P |
128 | return NULL; |
129 | } | |
130 | rand->name_id = name_id; | |
6c9bc258 TM |
131 | if ((rand->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) { |
132 | evp_rand_free(rand); | |
133 | return NULL; | |
134 | } | |
309a78aa | 135 | rand->description = algodef->algorithm_description; |
15dfa092 P |
136 | rand->dispatch = fns; |
137 | for (; fns->function_id != 0; fns++) { | |
138 | switch (fns->function_id) { | |
139 | case OSSL_FUNC_RAND_NEWCTX: | |
140 | if (rand->newctx != NULL) | |
141 | break; | |
363b1e5d | 142 | rand->newctx = OSSL_FUNC_rand_newctx(fns); |
15dfa092 P |
143 | fnctxcnt++; |
144 | break; | |
145 | case OSSL_FUNC_RAND_FREECTX: | |
146 | if (rand->freectx != NULL) | |
147 | break; | |
363b1e5d | 148 | rand->freectx = OSSL_FUNC_rand_freectx(fns); |
15dfa092 P |
149 | fnctxcnt++; |
150 | break; | |
151 | case OSSL_FUNC_RAND_INSTANTIATE: | |
152 | if (rand->instantiate != NULL) | |
153 | break; | |
363b1e5d | 154 | rand->instantiate = OSSL_FUNC_rand_instantiate(fns); |
15dfa092 P |
155 | fnrandcnt++; |
156 | break; | |
157 | case OSSL_FUNC_RAND_UNINSTANTIATE: | |
158 | if (rand->uninstantiate != NULL) | |
159 | break; | |
363b1e5d | 160 | rand->uninstantiate = OSSL_FUNC_rand_uninstantiate(fns); |
15dfa092 P |
161 | fnrandcnt++; |
162 | break; | |
163 | case OSSL_FUNC_RAND_GENERATE: | |
164 | if (rand->generate != NULL) | |
165 | break; | |
363b1e5d | 166 | rand->generate = OSSL_FUNC_rand_generate(fns); |
15dfa092 P |
167 | fnrandcnt++; |
168 | break; | |
169 | case OSSL_FUNC_RAND_RESEED: | |
170 | if (rand->reseed != NULL) | |
171 | break; | |
363b1e5d | 172 | rand->reseed = OSSL_FUNC_rand_reseed(fns); |
15dfa092 P |
173 | break; |
174 | case OSSL_FUNC_RAND_NONCE: | |
175 | if (rand->nonce != NULL) | |
176 | break; | |
363b1e5d | 177 | rand->nonce = OSSL_FUNC_rand_nonce(fns); |
15dfa092 | 178 | break; |
15dfa092 | 179 | case OSSL_FUNC_RAND_ENABLE_LOCKING: |
f000e828 | 180 | if (rand->enable_locking != NULL) |
15dfa092 | 181 | break; |
363b1e5d | 182 | rand->enable_locking = OSSL_FUNC_rand_enable_locking(fns); |
f626c3ff | 183 | fnenablelockcnt++; |
15dfa092 P |
184 | break; |
185 | case OSSL_FUNC_RAND_LOCK: | |
f000e828 | 186 | if (rand->lock != NULL) |
15dfa092 | 187 | break; |
363b1e5d | 188 | rand->lock = OSSL_FUNC_rand_lock(fns); |
f000e828 | 189 | fnlockcnt++; |
15dfa092 P |
190 | break; |
191 | case OSSL_FUNC_RAND_UNLOCK: | |
f000e828 | 192 | if (rand->unlock != NULL) |
15dfa092 | 193 | break; |
363b1e5d | 194 | rand->unlock = OSSL_FUNC_rand_unlock(fns); |
f000e828 | 195 | fnlockcnt++; |
15dfa092 P |
196 | break; |
197 | case OSSL_FUNC_RAND_GETTABLE_PARAMS: | |
198 | if (rand->gettable_params != NULL) | |
199 | break; | |
200 | rand->gettable_params = | |
363b1e5d | 201 | OSSL_FUNC_rand_gettable_params(fns); |
15dfa092 P |
202 | break; |
203 | case OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS: | |
204 | if (rand->gettable_ctx_params != NULL) | |
205 | break; | |
206 | rand->gettable_ctx_params = | |
363b1e5d | 207 | OSSL_FUNC_rand_gettable_ctx_params(fns); |
15dfa092 P |
208 | break; |
209 | case OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS: | |
210 | if (rand->settable_ctx_params != NULL) | |
211 | break; | |
212 | rand->settable_ctx_params = | |
363b1e5d | 213 | OSSL_FUNC_rand_settable_ctx_params(fns); |
15dfa092 P |
214 | break; |
215 | case OSSL_FUNC_RAND_GET_PARAMS: | |
216 | if (rand->get_params != NULL) | |
217 | break; | |
363b1e5d | 218 | rand->get_params = OSSL_FUNC_rand_get_params(fns); |
15dfa092 P |
219 | break; |
220 | case OSSL_FUNC_RAND_GET_CTX_PARAMS: | |
221 | if (rand->get_ctx_params != NULL) | |
222 | break; | |
363b1e5d | 223 | rand->get_ctx_params = OSSL_FUNC_rand_get_ctx_params(fns); |
132abb21 | 224 | fnctxcnt++; |
15dfa092 P |
225 | break; |
226 | case OSSL_FUNC_RAND_SET_CTX_PARAMS: | |
227 | if (rand->set_ctx_params != NULL) | |
228 | break; | |
363b1e5d | 229 | rand->set_ctx_params = OSSL_FUNC_rand_set_ctx_params(fns); |
15dfa092 | 230 | break; |
714a1bb3 P |
231 | case OSSL_FUNC_RAND_VERIFY_ZEROIZATION: |
232 | if (rand->verify_zeroization != NULL) | |
233 | break; | |
363b1e5d | 234 | rand->verify_zeroization = OSSL_FUNC_rand_verify_zeroization(fns); |
714a1bb3 | 235 | #ifdef FIPS_MODULE |
f000e828 | 236 | fnzeroizecnt++; |
714a1bb3 P |
237 | #endif |
238 | break; | |
15dfa092 P |
239 | } |
240 | } | |
f000e828 P |
241 | /* |
242 | * In order to be a consistent set of functions we must have at least | |
243 | * a complete set of "rand" functions and a complete set of context | |
244 | * management functions. In FIPS mode, we also require the zeroization | |
245 | * verification function. | |
246 | * | |
247 | * In addition, if locking can be enabled, we need a complete set of | |
248 | * locking functions. | |
249 | */ | |
714a1bb3 | 250 | if (fnrandcnt != 3 |
132abb21 | 251 | || fnctxcnt != 3 |
f626c3ff P |
252 | || (fnenablelockcnt != 0 && fnenablelockcnt != 1) |
253 | || (fnlockcnt != 0 && fnlockcnt != 2) | |
714a1bb3 | 254 | #ifdef FIPS_MODULE |
f000e828 | 255 | || fnzeroizecnt != 1 |
714a1bb3 P |
256 | #endif |
257 | ) { | |
15dfa092 P |
258 | evp_rand_free(rand); |
259 | ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); | |
260 | return NULL; | |
261 | } | |
f000e828 P |
262 | |
263 | if (prov != NULL && !ossl_provider_up_ref(prov)) { | |
264 | evp_rand_free(rand); | |
265 | ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); | |
266 | return NULL; | |
267 | } | |
15dfa092 | 268 | rand->prov = prov; |
15dfa092 P |
269 | |
270 | return rand; | |
271 | } | |
272 | ||
b4250010 | 273 | EVP_RAND *EVP_RAND_fetch(OSSL_LIB_CTX *libctx, const char *algorithm, |
f000e828 | 274 | const char *properties) |
15dfa092 P |
275 | { |
276 | return evp_generic_fetch(libctx, OSSL_OP_RAND, algorithm, properties, | |
309a78aa | 277 | evp_rand_from_algorithm, evp_rand_up_ref, |
15dfa092 P |
278 | evp_rand_free); |
279 | } | |
280 | ||
281 | int EVP_RAND_up_ref(EVP_RAND *rand) | |
282 | { | |
283 | return evp_rand_up_ref(rand); | |
284 | } | |
285 | ||
286 | void EVP_RAND_free(EVP_RAND *rand) | |
287 | { | |
288 | evp_rand_free(rand); | |
289 | } | |
290 | ||
bcd5d3a2 | 291 | int evp_rand_get_number(const EVP_RAND *rand) |
15dfa092 P |
292 | { |
293 | return rand->name_id; | |
294 | } | |
295 | ||
ed576acd | 296 | const char *EVP_RAND_get0_name(const EVP_RAND *rand) |
15dfa092 | 297 | { |
6c9bc258 | 298 | return rand->type_name; |
15dfa092 P |
299 | } |
300 | ||
ed576acd | 301 | const char *EVP_RAND_get0_description(const EVP_RAND *rand) |
03888233 RL |
302 | { |
303 | return rand->description; | |
304 | } | |
305 | ||
15dfa092 P |
306 | int EVP_RAND_is_a(const EVP_RAND *rand, const char *name) |
307 | { | |
308 | return evp_is_a(rand->prov, rand->name_id, NULL, name); | |
309 | } | |
310 | ||
ed576acd | 311 | const OSSL_PROVIDER *EVP_RAND_get0_provider(const EVP_RAND *rand) |
15dfa092 P |
312 | { |
313 | return rand->prov; | |
314 | } | |
315 | ||
316 | int EVP_RAND_get_params(EVP_RAND *rand, OSSL_PARAM params[]) | |
317 | { | |
318 | if (rand->get_params != NULL) | |
319 | return rand->get_params(params); | |
320 | return 1; | |
321 | } | |
322 | ||
4640cd00 P |
323 | static int evp_rand_ctx_up_ref(EVP_RAND_CTX *ctx) |
324 | { | |
325 | int ref = 0; | |
326 | ||
327 | return CRYPTO_UP_REF(&ctx->refcnt, &ref, ctx->refcnt_lock); | |
328 | } | |
329 | ||
f000e828 | 330 | EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent) |
15dfa092 P |
331 | { |
332 | EVP_RAND_CTX *ctx; | |
333 | void *parent_ctx = NULL; | |
334 | const OSSL_DISPATCH *parent_dispatch = NULL; | |
335 | ||
f000e828 | 336 | if (rand == NULL) { |
9311d0c4 | 337 | ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_NULL_ALGORITHM); |
15dfa092 | 338 | return NULL; |
f000e828 | 339 | } |
15dfa092 | 340 | |
f000e828 | 341 | ctx = OPENSSL_zalloc(sizeof(*ctx)); |
4640cd00 P |
342 | if (ctx == NULL || (ctx->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL) { |
343 | OPENSSL_free(ctx); | |
9311d0c4 | 344 | ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); |
15dfa092 | 345 | return NULL; |
f000e828 | 346 | } |
15dfa092 | 347 | if (parent != NULL) { |
4640cd00 | 348 | if (!evp_rand_ctx_up_ref(parent)) { |
9311d0c4 | 349 | ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); |
4640cd00 | 350 | CRYPTO_THREAD_lock_free(ctx->refcnt_lock); |
f000e828 P |
351 | OPENSSL_free(ctx); |
352 | return NULL; | |
353 | } | |
7c14d0c1 | 354 | parent_ctx = parent->algctx; |
15dfa092 P |
355 | parent_dispatch = parent->meth->dispatch; |
356 | } | |
7c14d0c1 SL |
357 | if ((ctx->algctx = rand->newctx(ossl_provider_ctx(rand->prov), parent_ctx, |
358 | parent_dispatch)) == NULL | |
15dfa092 | 359 | || !EVP_RAND_up_ref(rand)) { |
9311d0c4 | 360 | ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); |
7c14d0c1 | 361 | rand->freectx(ctx->algctx); |
4640cd00 | 362 | CRYPTO_THREAD_lock_free(ctx->refcnt_lock); |
15dfa092 | 363 | OPENSSL_free(ctx); |
4640cd00 | 364 | EVP_RAND_CTX_free(parent); |
15dfa092 P |
365 | return NULL; |
366 | } | |
367 | ctx->meth = rand; | |
4640cd00 P |
368 | ctx->parent = parent; |
369 | ctx->refcnt = 1; | |
15dfa092 P |
370 | return ctx; |
371 | } | |
372 | ||
373 | void EVP_RAND_CTX_free(EVP_RAND_CTX *ctx) | |
374 | { | |
543e740b RS |
375 | int ref = 0; |
376 | EVP_RAND_CTX *parent; | |
377 | ||
378 | if (ctx == NULL) | |
379 | return; | |
380 | ||
381 | CRYPTO_DOWN_REF(&ctx->refcnt, &ref, ctx->refcnt_lock); | |
382 | if (ref > 0) | |
383 | return; | |
384 | parent = ctx->parent; | |
7c14d0c1 SL |
385 | ctx->meth->freectx(ctx->algctx); |
386 | ctx->algctx = NULL; | |
543e740b RS |
387 | EVP_RAND_free(ctx->meth); |
388 | CRYPTO_THREAD_lock_free(ctx->refcnt_lock); | |
389 | OPENSSL_free(ctx); | |
390 | EVP_RAND_CTX_free(parent); | |
15dfa092 P |
391 | } |
392 | ||
ed576acd | 393 | EVP_RAND *EVP_RAND_CTX_get0_rand(EVP_RAND_CTX *ctx) |
15dfa092 P |
394 | { |
395 | return ctx->meth; | |
396 | } | |
397 | ||
7dc38bea P |
398 | static int evp_rand_get_ctx_params_locked(EVP_RAND_CTX *ctx, |
399 | OSSL_PARAM params[]) | |
400 | { | |
7c14d0c1 | 401 | return ctx->meth->get_ctx_params(ctx->algctx, params); |
7dc38bea P |
402 | } |
403 | ||
e494fac7 | 404 | int EVP_RAND_CTX_get_params(EVP_RAND_CTX *ctx, OSSL_PARAM params[]) |
15dfa092 | 405 | { |
132abb21 | 406 | int res; |
714a1bb3 | 407 | |
132abb21 P |
408 | if (!evp_rand_lock(ctx)) |
409 | return 0; | |
7dc38bea | 410 | res = evp_rand_get_ctx_params_locked(ctx, params); |
132abb21 | 411 | evp_rand_unlock(ctx); |
714a1bb3 | 412 | return res; |
15dfa092 P |
413 | } |
414 | ||
7dc38bea P |
415 | static int evp_rand_set_ctx_params_locked(EVP_RAND_CTX *ctx, |
416 | const OSSL_PARAM params[]) | |
417 | { | |
7dc38bea | 418 | if (ctx->meth->set_ctx_params != NULL) |
7c14d0c1 | 419 | return ctx->meth->set_ctx_params(ctx->algctx, params); |
7dc38bea P |
420 | return 1; |
421 | } | |
422 | ||
e494fac7 | 423 | int EVP_RAND_CTX_set_params(EVP_RAND_CTX *ctx, const OSSL_PARAM params[]) |
15dfa092 | 424 | { |
7dc38bea | 425 | int res; |
714a1bb3 | 426 | |
7dc38bea P |
427 | if (!evp_rand_lock(ctx)) |
428 | return 0; | |
429 | res = evp_rand_set_ctx_params_locked(ctx, params); | |
430 | evp_rand_unlock(ctx); | |
714a1bb3 | 431 | return res; |
15dfa092 P |
432 | } |
433 | ||
434 | const OSSL_PARAM *EVP_RAND_gettable_params(const EVP_RAND *rand) | |
435 | { | |
18ec26ba P |
436 | if (rand->gettable_params == NULL) |
437 | return NULL; | |
ed576acd | 438 | return rand->gettable_params(ossl_provider_ctx(EVP_RAND_get0_provider(rand))); |
15dfa092 P |
439 | } |
440 | ||
441 | const OSSL_PARAM *EVP_RAND_gettable_ctx_params(const EVP_RAND *rand) | |
442 | { | |
caa60428 P |
443 | void *provctx; |
444 | ||
d8e52fd0 | 445 | if (rand->gettable_ctx_params == NULL) |
18ec26ba | 446 | return NULL; |
ed576acd | 447 | provctx = ossl_provider_ctx(EVP_RAND_get0_provider(rand)); |
caa60428 | 448 | return rand->gettable_ctx_params(NULL, provctx); |
15dfa092 P |
449 | } |
450 | ||
451 | const OSSL_PARAM *EVP_RAND_settable_ctx_params(const EVP_RAND *rand) | |
452 | { | |
caa60428 P |
453 | void *provctx; |
454 | ||
d8e52fd0 | 455 | if (rand->settable_ctx_params == NULL) |
18ec26ba | 456 | return NULL; |
ed576acd | 457 | provctx = ossl_provider_ctx(EVP_RAND_get0_provider(rand)); |
caa60428 P |
458 | return rand->settable_ctx_params(NULL, provctx); |
459 | } | |
460 | ||
461 | const OSSL_PARAM *EVP_RAND_CTX_gettable_params(EVP_RAND_CTX *ctx) | |
462 | { | |
463 | void *provctx; | |
464 | ||
465 | if (ctx->meth->gettable_ctx_params == NULL) | |
466 | return NULL; | |
ed576acd | 467 | provctx = ossl_provider_ctx(EVP_RAND_get0_provider(ctx->meth)); |
7c14d0c1 | 468 | return ctx->meth->gettable_ctx_params(ctx->algctx, provctx); |
caa60428 P |
469 | } |
470 | ||
471 | const OSSL_PARAM *EVP_RAND_CTX_settable_params(EVP_RAND_CTX *ctx) | |
472 | { | |
473 | void *provctx; | |
474 | ||
475 | if (ctx->meth->settable_ctx_params == NULL) | |
476 | return NULL; | |
ed576acd | 477 | provctx = ossl_provider_ctx(EVP_RAND_get0_provider(ctx->meth)); |
7c14d0c1 | 478 | return ctx->meth->settable_ctx_params(ctx->algctx, provctx); |
15dfa092 P |
479 | } |
480 | ||
b4250010 | 481 | void EVP_RAND_do_all_provided(OSSL_LIB_CTX *libctx, |
15dfa092 P |
482 | void (*fn)(EVP_RAND *rand, void *arg), |
483 | void *arg) | |
484 | { | |
485 | evp_generic_do_all(libctx, OSSL_OP_RAND, | |
486 | (void (*)(void *, void *))fn, arg, | |
cd770738 RL |
487 | evp_rand_from_algorithm, evp_rand_up_ref, |
488 | evp_rand_free); | |
15dfa092 P |
489 | } |
490 | ||
d84f5515 MC |
491 | int EVP_RAND_names_do_all(const EVP_RAND *rand, |
492 | void (*fn)(const char *name, void *data), | |
493 | void *data) | |
15dfa092 P |
494 | { |
495 | if (rand->prov != NULL) | |
d84f5515 MC |
496 | return evp_names_do_all(rand->prov, rand->name_id, fn, data); |
497 | ||
498 | return 1; | |
15dfa092 P |
499 | } |
500 | ||
7dc38bea P |
501 | static int evp_rand_instantiate_locked |
502 | (EVP_RAND_CTX *ctx, unsigned int strength, int prediction_resistance, | |
671ff5c7 | 503 | const unsigned char *pstr, size_t pstr_len, const OSSL_PARAM params[]) |
7dc38bea | 504 | { |
7c14d0c1 | 505 | return ctx->meth->instantiate(ctx->algctx, strength, prediction_resistance, |
671ff5c7 | 506 | pstr, pstr_len, params); |
7dc38bea P |
507 | } |
508 | ||
f000e828 P |
509 | int EVP_RAND_instantiate(EVP_RAND_CTX *ctx, unsigned int strength, |
510 | int prediction_resistance, | |
671ff5c7 P |
511 | const unsigned char *pstr, size_t pstr_len, |
512 | const OSSL_PARAM params[]) | |
15dfa092 | 513 | { |
714a1bb3 P |
514 | int res; |
515 | ||
516 | if (!evp_rand_lock(ctx)) | |
517 | return 0; | |
7dc38bea | 518 | res = evp_rand_instantiate_locked(ctx, strength, prediction_resistance, |
671ff5c7 | 519 | pstr, pstr_len, params); |
714a1bb3 P |
520 | evp_rand_unlock(ctx); |
521 | return res; | |
15dfa092 P |
522 | } |
523 | ||
7dc38bea P |
524 | static int evp_rand_uninstantiate_locked(EVP_RAND_CTX *ctx) |
525 | { | |
7c14d0c1 | 526 | return ctx->meth->uninstantiate(ctx->algctx); |
7dc38bea P |
527 | } |
528 | ||
f000e828 | 529 | int EVP_RAND_uninstantiate(EVP_RAND_CTX *ctx) |
15dfa092 | 530 | { |
714a1bb3 P |
531 | int res; |
532 | ||
533 | if (!evp_rand_lock(ctx)) | |
534 | return 0; | |
7dc38bea | 535 | res = evp_rand_uninstantiate_locked(ctx); |
714a1bb3 P |
536 | evp_rand_unlock(ctx); |
537 | return res; | |
15dfa092 P |
538 | } |
539 | ||
7dc38bea P |
540 | static int evp_rand_generate_locked(EVP_RAND_CTX *ctx, unsigned char *out, |
541 | size_t outlen, unsigned int strength, | |
542 | int prediction_resistance, | |
543 | const unsigned char *addin, | |
544 | size_t addin_len) | |
15dfa092 | 545 | { |
22f7f424 P |
546 | size_t chunk, max_request = 0; |
547 | OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; | |
714a1bb3 | 548 | |
03bede0c | 549 | params[0] = OSSL_PARAM_construct_size_t(OSSL_RAND_PARAM_MAX_REQUEST, |
22f7f424 P |
550 | &max_request); |
551 | if (!evp_rand_get_ctx_params_locked(ctx, params) | |
552 | || max_request == 0) { | |
9311d0c4 | 553 | ERR_raise(ERR_LIB_EVP, EVP_R_UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE); |
22f7f424 | 554 | return 0; |
714a1bb3 P |
555 | } |
556 | for (; outlen > 0; outlen -= chunk, out += chunk) { | |
22f7f424 | 557 | chunk = outlen > max_request ? max_request : outlen; |
7c14d0c1 | 558 | if (!ctx->meth->generate(ctx->algctx, out, chunk, strength, |
f000e828 | 559 | prediction_resistance, addin, addin_len)) { |
9311d0c4 | 560 | ERR_raise(ERR_LIB_EVP, EVP_R_GENERATE_ERROR); |
7dc38bea | 561 | return 0; |
f000e828 P |
562 | } |
563 | /* | |
564 | * Prediction resistance is only relevant the first time around, | |
565 | * subsequently, the DRBG has already been properly reseeded. | |
566 | */ | |
567 | prediction_resistance = 0; | |
714a1bb3 | 568 | } |
7dc38bea | 569 | return 1; |
15dfa092 P |
570 | } |
571 | ||
7dc38bea P |
572 | int EVP_RAND_generate(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen, |
573 | unsigned int strength, int prediction_resistance, | |
574 | const unsigned char *addin, size_t addin_len) | |
15dfa092 | 575 | { |
7dc38bea | 576 | int res; |
714a1bb3 P |
577 | |
578 | if (!evp_rand_lock(ctx)) | |
579 | return 0; | |
7dc38bea P |
580 | res = evp_rand_generate_locked(ctx, out, outlen, strength, |
581 | prediction_resistance, addin, addin_len); | |
714a1bb3 P |
582 | evp_rand_unlock(ctx); |
583 | return res; | |
15dfa092 P |
584 | } |
585 | ||
7dc38bea P |
586 | static int evp_rand_reseed_locked(EVP_RAND_CTX *ctx, int prediction_resistance, |
587 | const unsigned char *ent, size_t ent_len, | |
588 | const unsigned char *addin, size_t addin_len) | |
589 | { | |
590 | if (ctx->meth->reseed != NULL) | |
7c14d0c1 | 591 | return ctx->meth->reseed(ctx->algctx, prediction_resistance, |
7dc38bea P |
592 | ent, ent_len, addin, addin_len); |
593 | return 1; | |
594 | } | |
595 | ||
596 | int EVP_RAND_reseed(EVP_RAND_CTX *ctx, int prediction_resistance, | |
597 | const unsigned char *ent, size_t ent_len, | |
598 | const unsigned char *addin, size_t addin_len) | |
15dfa092 | 599 | { |
7dc38bea | 600 | int res; |
714a1bb3 P |
601 | |
602 | if (!evp_rand_lock(ctx)) | |
603 | return 0; | |
7dc38bea P |
604 | res = evp_rand_reseed_locked(ctx, prediction_resistance, |
605 | ent, ent_len, addin, addin_len); | |
714a1bb3 P |
606 | evp_rand_unlock(ctx); |
607 | return res; | |
608 | } | |
609 | ||
7dc38bea | 610 | static unsigned int evp_rand_strength_locked(EVP_RAND_CTX *ctx) |
714a1bb3 | 611 | { |
7dc38bea | 612 | OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; |
22f7f424 | 613 | unsigned int strength = 0; |
714a1bb3 | 614 | |
22f7f424 P |
615 | params[0] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH, &strength); |
616 | if (!evp_rand_get_ctx_params_locked(ctx, params)) | |
617 | return 0; | |
618 | return strength; | |
15dfa092 P |
619 | } |
620 | ||
ed576acd | 621 | unsigned int EVP_RAND_get_strength(EVP_RAND_CTX *ctx) |
7dc38bea P |
622 | { |
623 | unsigned int res; | |
624 | ||
625 | if (!evp_rand_lock(ctx)) | |
626 | return 0; | |
627 | res = evp_rand_strength_locked(ctx); | |
628 | evp_rand_unlock(ctx); | |
629 | return res; | |
630 | } | |
631 | ||
632 | static int evp_rand_nonce_locked(EVP_RAND_CTX *ctx, unsigned char *out, | |
633 | size_t outlen) | |
634 | { | |
635 | unsigned int str = evp_rand_strength_locked(ctx); | |
636 | ||
637 | if (ctx->meth->nonce == NULL) | |
638 | return 0; | |
7c14d0c1 | 639 | if (ctx->meth->nonce(ctx->algctx, out, str, outlen, outlen)) |
7dc38bea P |
640 | return 1; |
641 | return evp_rand_generate_locked(ctx, out, outlen, str, 0, NULL, 0); | |
642 | } | |
643 | ||
644 | int EVP_RAND_nonce(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen) | |
645 | { | |
646 | int res; | |
647 | ||
648 | if (!evp_rand_lock(ctx)) | |
649 | return 0; | |
650 | res = evp_rand_nonce_locked(ctx, out, outlen); | |
651 | evp_rand_unlock(ctx); | |
652 | return res; | |
653 | } | |
654 | ||
ed576acd | 655 | int EVP_RAND_get_state(EVP_RAND_CTX *ctx) |
15dfa092 | 656 | { |
714a1bb3 | 657 | OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; |
7dc38bea | 658 | int state; |
714a1bb3 | 659 | |
7dc38bea | 660 | params[0] = OSSL_PARAM_construct_int(OSSL_RAND_PARAM_STATE, &state); |
e494fac7 | 661 | if (!EVP_RAND_CTX_get_params(ctx, params)) |
7dc38bea P |
662 | state = EVP_RAND_STATE_ERROR; |
663 | return state; | |
15dfa092 P |
664 | } |
665 | ||
7dc38bea P |
666 | static int evp_rand_verify_zeroization_locked(EVP_RAND_CTX *ctx) |
667 | { | |
668 | if (ctx->meth->verify_zeroization != NULL) | |
7c14d0c1 | 669 | return ctx->meth->verify_zeroization(ctx->algctx); |
7dc38bea P |
670 | return 0; |
671 | } | |
672 | ||
f000e828 | 673 | int EVP_RAND_verify_zeroization(EVP_RAND_CTX *ctx) |
714a1bb3 | 674 | { |
7dc38bea | 675 | int res; |
714a1bb3 | 676 | |
7dc38bea P |
677 | if (!evp_rand_lock(ctx)) |
678 | return 0; | |
679 | res = evp_rand_verify_zeroization_locked(ctx); | |
680 | evp_rand_unlock(ctx); | |
714a1bb3 P |
681 | return res; |
682 | } |