2 * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
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
10 #include <openssl/evp.h>
14 #include "internal/cryptlib.h"
15 #include <openssl/engine.h>
16 #include <openssl/evp.h>
17 #include <openssl/x509v3.h>
18 #include <openssl/rand.h>
19 #include <openssl/core.h>
20 #include <openssl/core_names.h>
21 #include <openssl/crypto.h>
22 #include "crypto/asn1.h"
23 #include "crypto/evp.h"
24 #include "internal/numbers.h"
25 #include "internal/provider.h"
26 #include "evp_local.h"
28 static int evp_rand_up_ref(void *vrand)
30 EVP_RAND *rand = (EVP_RAND *)vrand;
34 return CRYPTO_UP_REF(&rand->refcnt, &ref, rand->lock);
38 static void evp_rand_free(void *vrand){
39 EVP_RAND *rand = (EVP_RAND *)vrand;
43 CRYPTO_DOWN_REF(&rand->refcnt, &ref, rand->lock);
45 ossl_provider_free(rand->prov);
46 CRYPTO_THREAD_lock_free(rand->lock);
52 static void *evp_rand_new(void)
54 EVP_RAND *rand = NULL;
56 if ((rand = OPENSSL_zalloc(sizeof(*rand))) == NULL
57 || (rand->lock = CRYPTO_THREAD_lock_new()) == NULL) {
65 /* Enable locking of the underlying DRBG/RAND if available */
66 int EVP_RAND_CTX_enable_locking(EVP_RAND_CTX *rand)
68 if (rand->meth->enable_prov_locking != NULL)
69 return rand->meth->enable_prov_locking(rand->data);
73 /* Lock the underlying DRBG/RAND if available */
74 static int evp_rand_lock(EVP_RAND_CTX *rand)
76 if (rand->meth->prov_lock != NULL)
77 return rand->meth->prov_lock(rand->data);
81 /* Unlock the underlying DRBG/RAND if available */
82 static void evp_rand_unlock(EVP_RAND_CTX *rand)
84 if (rand->meth->prov_unlock != NULL)
85 rand->meth->prov_unlock(rand->data);
88 static void *evp_rand_from_dispatch(int name_id,
89 const OSSL_DISPATCH *fns,
92 EVP_RAND *rand = NULL;
93 int fnrandcnt = 0, fnctxcnt = 0;
98 if ((rand = evp_rand_new()) == NULL) {
99 EVPerr(0, ERR_R_MALLOC_FAILURE);
102 rand->name_id = name_id;
103 rand->dispatch = fns;
104 for (; fns->function_id != 0; fns++) {
105 switch (fns->function_id) {
106 case OSSL_FUNC_RAND_NEWCTX:
107 if (rand->newctx != NULL)
109 rand->newctx = OSSL_get_OP_rand_newctx(fns);
112 case OSSL_FUNC_RAND_FREECTX:
113 if (rand->freectx != NULL)
115 rand->freectx = OSSL_get_OP_rand_freectx(fns);
118 case OSSL_FUNC_RAND_INSTANTIATE:
119 if (rand->instantiate != NULL)
121 rand->instantiate = OSSL_get_OP_rand_instantiate(fns);
124 case OSSL_FUNC_RAND_UNINSTANTIATE:
125 if (rand->uninstantiate != NULL)
127 rand->uninstantiate = OSSL_get_OP_rand_uninstantiate(fns);
130 case OSSL_FUNC_RAND_GENERATE:
131 if (rand->generate != NULL)
133 rand->generate = OSSL_get_OP_rand_generate(fns);
136 case OSSL_FUNC_RAND_RESEED:
137 if (rand->reseed != NULL)
139 rand->reseed = OSSL_get_OP_rand_reseed(fns);
141 case OSSL_FUNC_RAND_NONCE:
142 if (rand->nonce != NULL)
144 rand->nonce = OSSL_get_OP_rand_nonce(fns);
146 case OSSL_FUNC_RAND_SET_CALLBACKS:
147 if (rand->set_callbacks != NULL)
149 rand->set_callbacks = OSSL_get_OP_rand_set_callbacks(fns);
151 case OSSL_FUNC_RAND_ENABLE_LOCKING:
152 if (rand->enable_prov_locking != NULL)
154 rand->enable_prov_locking = OSSL_get_OP_rand_enable_locking(fns);
156 case OSSL_FUNC_RAND_LOCK:
157 if (rand->prov_lock != NULL)
159 rand->prov_lock = OSSL_get_OP_rand_lock(fns);
161 case OSSL_FUNC_RAND_UNLOCK:
162 if (rand->prov_unlock != NULL)
164 rand->prov_unlock = OSSL_get_OP_rand_unlock(fns);
166 case OSSL_FUNC_RAND_GETTABLE_PARAMS:
167 if (rand->gettable_params != NULL)
169 rand->gettable_params =
170 OSSL_get_OP_rand_gettable_params(fns);
172 case OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS:
173 if (rand->gettable_ctx_params != NULL)
175 rand->gettable_ctx_params =
176 OSSL_get_OP_rand_gettable_ctx_params(fns);
178 case OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS:
179 if (rand->settable_ctx_params != NULL)
181 rand->settable_ctx_params =
182 OSSL_get_OP_rand_settable_ctx_params(fns);
184 case OSSL_FUNC_RAND_GET_PARAMS:
185 if (rand->get_params != NULL)
187 rand->get_params = OSSL_get_OP_rand_get_params(fns);
189 case OSSL_FUNC_RAND_GET_CTX_PARAMS:
190 if (rand->get_ctx_params != NULL)
192 rand->get_ctx_params = OSSL_get_OP_rand_get_ctx_params(fns);
194 case OSSL_FUNC_RAND_SET_CTX_PARAMS:
195 if (rand->set_ctx_params != NULL)
197 rand->set_ctx_params = OSSL_get_OP_rand_set_ctx_params(fns);
199 case OSSL_FUNC_RAND_VERIFY_ZEROIZATION:
200 if (rand->verify_zeroization != NULL)
202 rand->verify_zeroization = OSSL_get_OP_rand_verify_zeroization(fns);
216 * In order to be a consistent set of functions we must have at least
217 * a complete set of "rand" functions and a complete set of context
218 * management functions. In FIPS mode, we also require the zeroization
219 * verification function.
222 ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
227 ossl_provider_up_ref(prov);
232 EVP_RAND *EVP_RAND_fetch(OPENSSL_CTX *libctx, const char *algorithm,
233 const char *properties)
235 return evp_generic_fetch(libctx, OSSL_OP_RAND, algorithm, properties,
236 evp_rand_from_dispatch, evp_rand_up_ref,
240 int EVP_RAND_up_ref(EVP_RAND *rand)
242 return evp_rand_up_ref(rand);
245 void EVP_RAND_free(EVP_RAND *rand)
250 int EVP_RAND_number(const EVP_RAND *rand)
252 return rand->name_id;
255 const char *EVP_RAND_name(const EVP_RAND *rand)
257 return evp_first_name(rand->prov, rand->name_id);
260 int EVP_RAND_is_a(const EVP_RAND *rand, const char *name)
262 return evp_is_a(rand->prov, rand->name_id, NULL, name);
265 const OSSL_PROVIDER *EVP_RAND_provider(const EVP_RAND *rand)
270 int EVP_RAND_get_params(EVP_RAND *rand, OSSL_PARAM params[])
272 if (rand->get_params != NULL)
273 return rand->get_params(params);
277 EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, int secure, EVP_RAND_CTX *parent)
280 void *parent_ctx = NULL;
281 const OSSL_DISPATCH *parent_dispatch = NULL;
286 ctx = OPENSSL_zalloc(sizeof(EVP_RAND_CTX));
289 if (parent != NULL) {
290 EVP_RAND_CTX_enable_locking(parent);
291 parent_ctx = parent->data;
292 parent_dispatch = parent->meth->dispatch;
294 if ((ctx->data = rand->newctx(ossl_provider_ctx(rand->prov), secure,
295 parent_ctx, parent_dispatch)) == NULL
296 || !EVP_RAND_up_ref(rand)) {
297 EVPerr(0, ERR_R_MALLOC_FAILURE);
298 rand->freectx(ctx->data);
306 void EVP_RAND_CTX_free(EVP_RAND_CTX *ctx)
309 ctx->meth->freectx(ctx->data);
311 EVP_RAND_CTX_free(ctx->parent);
312 EVP_RAND_free(ctx->meth);
317 EVP_RAND *EVP_RAND_CTX_rand(EVP_RAND_CTX *ctx)
322 int EVP_RAND_CTX_get_params(EVP_RAND_CTX *ctx, OSSL_PARAM params[])
326 if (ctx->meth->get_ctx_params != NULL) {
327 if (!evp_rand_lock(ctx))
329 res = ctx->meth->get_ctx_params(ctx->data, params);
330 evp_rand_unlock(ctx);
335 int EVP_RAND_CTX_set_params(EVP_RAND_CTX *ctx, const OSSL_PARAM params[])
339 if (ctx->meth->set_ctx_params != NULL) {
340 if (!evp_rand_lock(ctx))
342 res = ctx->meth->set_ctx_params(ctx->data, params);
343 evp_rand_unlock(ctx);
344 /* Clear out the cache state because the values can change on a set */
346 ctx->max_request = 0;
351 const OSSL_PARAM *EVP_RAND_gettable_params(const EVP_RAND *rand)
353 if (rand->gettable_params == NULL)
355 return rand->gettable_params();
358 const OSSL_PARAM *EVP_RAND_gettable_ctx_params(const EVP_RAND *rand)
360 if (rand->gettable_ctx_params == NULL)
362 return rand->gettable_ctx_params();
365 const OSSL_PARAM *EVP_RAND_settable_ctx_params(const EVP_RAND *rand)
367 if (rand->settable_ctx_params == NULL)
369 return rand->settable_ctx_params();
372 void EVP_RAND_do_all_provided(OPENSSL_CTX *libctx,
373 void (*fn)(EVP_RAND *rand, void *arg),
376 evp_generic_do_all(libctx, OSSL_OP_RAND,
377 (void (*)(void *, void *))fn, arg,
378 evp_rand_from_dispatch, evp_rand_free);
381 void EVP_RAND_names_do_all(const EVP_RAND *rand,
382 void (*fn)(const char *name, void *data),
385 if (rand->prov != NULL)
386 evp_names_do_all(rand->prov, rand->name_id, fn, data);
389 int EVP_RAND_CTX_instantiate(EVP_RAND_CTX *ctx, unsigned int strength,
390 int prediction_resistance,
391 const unsigned char *pstr, size_t pstr_len)
395 if (!evp_rand_lock(ctx))
397 res = ctx->meth->instantiate(ctx->data, strength, prediction_resistance,
399 evp_rand_unlock(ctx);
403 int EVP_RAND_CTX_uninstantiate(EVP_RAND_CTX *ctx)
407 if (!evp_rand_lock(ctx))
409 res = ctx->meth->uninstantiate(ctx->data);
410 evp_rand_unlock(ctx);
414 int EVP_RAND_CTX_generate(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen,
415 unsigned int strength, int prediction_resistance,
416 const unsigned char *addin, size_t addin_len)
419 OSSL_PARAM params[2];
422 if (!evp_rand_lock(ctx))
424 if (ctx->max_request == 0) {
425 params[0] = OSSL_PARAM_construct_size_t(OSSL_DRBG_PARAM_MAX_REQUEST,
427 params[1] = OSSL_PARAM_construct_end();
428 if (!EVP_RAND_CTX_get_params(ctx, params)
429 || ctx->max_request == 0)
432 for (; outlen > 0; outlen -= chunk, out += chunk) {
433 chunk = outlen > ctx->max_request ? ctx->max_request : outlen;
434 if (!ctx->meth->generate(ctx->data, out, chunk, strength,
435 prediction_resistance, addin, addin_len))
440 evp_rand_unlock(ctx);
444 int EVP_RAND_CTX_reseed(EVP_RAND_CTX *ctx, int prediction_resistance,
445 const unsigned char *ent, size_t ent_len,
446 const unsigned char *addin, size_t addin_len)
450 if (!evp_rand_lock(ctx))
452 if (ctx->meth->reseed != NULL)
453 res = ctx->meth->reseed(ctx->data, prediction_resistance,
454 ent, ent_len, addin, addin_len);
455 evp_rand_unlock(ctx);
459 int EVP_RAND_CTX_nonce(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen)
463 if (!evp_rand_lock(ctx))
465 if (ctx->meth->nonce == NULL
466 || !ctx->meth->nonce(ctx->data, out, 0, outlen, outlen))
467 res = ctx->meth->generate(ctx->data, out, outlen, 0, 0, NULL, 0);
468 evp_rand_unlock(ctx);
472 unsigned int EVP_RAND_CTX_strength(EVP_RAND_CTX *ctx)
474 OSSL_PARAM params[2];
477 if (ctx->strength == 0) {
478 params[0] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH,
480 params[1] = OSSL_PARAM_construct_end();
481 if (!evp_rand_lock(ctx))
483 res = EVP_RAND_CTX_get_params(ctx, params);
484 evp_rand_unlock(ctx);
488 return ctx->strength;
491 int EVP_RAND_CTX_state(EVP_RAND_CTX *ctx)
493 OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
496 params[0] = OSSL_PARAM_construct_int(OSSL_RAND_PARAM_STATE,
498 if (!evp_rand_lock(ctx))
500 res = EVP_RAND_CTX_get_params(ctx, params);
501 evp_rand_unlock(ctx);
503 status = EVP_RAND_STATE_ERROR;
507 int EVP_RAND_CTX_verify_zeroization(EVP_RAND_CTX *ctx)
511 if (ctx->meth->verify_zeroization != NULL) {
512 if (!evp_rand_lock(ctx))
514 res = ctx->meth->verify_zeroization(ctx->data);
515 evp_rand_unlock(ctx);