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