0f1745411ddcd1fd102fad165e6ddbbf47b4e0aa
[openssl.git] / crypto / evp / rand_meth.c
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
10 #include <openssl/evp.h>
11
12 #include <stdio.h>
13 #include <stdlib.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"
27
28 static int evp_rand_up_ref(void *vrand)
29 {
30     EVP_RAND *rand = (EVP_RAND *)vrand;
31     int ref = 0;
32
33     if (rand != NULL)
34         return CRYPTO_UP_REF(&rand->refcnt, &ref, rand->lock);
35     return 1;
36 }
37
38 static void evp_rand_free(void *vrand){
39     EVP_RAND *rand = (EVP_RAND *)vrand;
40     int ref = 0;
41
42     if (rand != NULL) {
43         CRYPTO_DOWN_REF(&rand->refcnt, &ref, rand->lock);
44         if (ref <= 0) {
45             ossl_provider_free(rand->prov);
46             CRYPTO_THREAD_lock_free(rand->lock);
47             OPENSSL_free(rand);
48         }
49     }
50 }
51
52 static void *evp_rand_new(void)
53 {
54     EVP_RAND *rand = NULL;
55
56     if ((rand = OPENSSL_zalloc(sizeof(*rand))) == NULL
57         || (rand->lock = CRYPTO_THREAD_lock_new()) == NULL) {
58         evp_rand_free(rand);
59         return NULL;
60     }
61     rand->refcnt = 1;
62     return rand;
63 }
64
65 /* Enable locking of the underlying DRBG/RAND if available */
66 int EVP_RAND_CTX_enable_locking(EVP_RAND_CTX *rand)
67 {
68     if (rand->meth->enable_prov_locking != NULL)
69         return rand->meth->enable_prov_locking(rand->data);
70     return 1;
71 }
72
73 /* Lock the underlying DRBG/RAND if available */
74 static int evp_rand_lock(EVP_RAND_CTX *rand)
75 {
76     if (rand->meth->prov_lock != NULL)
77         return rand->meth->prov_lock(rand->data);
78     return 1;
79 }
80
81 /* Unlock the underlying DRBG/RAND if available */
82 static void evp_rand_unlock(EVP_RAND_CTX *rand)
83 {
84     if (rand->meth->prov_unlock != NULL)
85         rand->meth->prov_unlock(rand->data);
86 }
87
88 static void *evp_rand_from_dispatch(int name_id,
89                                     const OSSL_DISPATCH *fns,
90                                     OSSL_PROVIDER *prov)
91 {
92     EVP_RAND *rand = NULL;
93     int fnrandcnt = 0, fnctxcnt = 0;
94 #ifdef FIPS_MODULE
95     int fnfipscnt = 0;
96 #endif
97
98     if ((rand = evp_rand_new()) == NULL) {
99         EVPerr(0, ERR_R_MALLOC_FAILURE);
100         return NULL;
101     }
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)
108                 break;
109             rand->newctx = OSSL_get_OP_rand_newctx(fns);
110             fnctxcnt++;
111             break;
112         case OSSL_FUNC_RAND_FREECTX:
113             if (rand->freectx != NULL)
114                 break;
115             rand->freectx = OSSL_get_OP_rand_freectx(fns);
116             fnctxcnt++;
117             break;
118         case OSSL_FUNC_RAND_INSTANTIATE:
119             if (rand->instantiate != NULL)
120                 break;
121             rand->instantiate = OSSL_get_OP_rand_instantiate(fns);
122             fnrandcnt++;
123             break;
124         case OSSL_FUNC_RAND_UNINSTANTIATE:
125              if (rand->uninstantiate != NULL)
126                 break;
127             rand->uninstantiate = OSSL_get_OP_rand_uninstantiate(fns);
128             fnrandcnt++;
129             break;
130         case OSSL_FUNC_RAND_GENERATE:
131             if (rand->generate != NULL)
132                 break;
133             rand->generate = OSSL_get_OP_rand_generate(fns);
134             fnrandcnt++;
135             break;
136         case OSSL_FUNC_RAND_RESEED:
137             if (rand->reseed != NULL)
138                 break;
139             rand->reseed = OSSL_get_OP_rand_reseed(fns);
140             break;
141         case OSSL_FUNC_RAND_NONCE:
142             if (rand->nonce != NULL)
143                 break;
144             rand->nonce = OSSL_get_OP_rand_nonce(fns);
145             break;
146         case OSSL_FUNC_RAND_SET_CALLBACKS:
147             if (rand->set_callbacks != NULL)
148                 break;
149             rand->set_callbacks = OSSL_get_OP_rand_set_callbacks(fns);
150             break;
151         case OSSL_FUNC_RAND_ENABLE_LOCKING:
152             if (rand->enable_prov_locking != NULL)
153                 break;
154             rand->enable_prov_locking = OSSL_get_OP_rand_enable_locking(fns);
155             break;
156         case OSSL_FUNC_RAND_LOCK:
157             if (rand->prov_lock != NULL)
158                 break;
159             rand->prov_lock = OSSL_get_OP_rand_lock(fns);
160             break;
161         case OSSL_FUNC_RAND_UNLOCK:
162             if (rand->prov_unlock != NULL)
163                 break;
164             rand->prov_unlock = OSSL_get_OP_rand_unlock(fns);
165             break;
166         case OSSL_FUNC_RAND_GETTABLE_PARAMS:
167             if (rand->gettable_params != NULL)
168                 break;
169             rand->gettable_params =
170                 OSSL_get_OP_rand_gettable_params(fns);
171             break;
172         case OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS:
173             if (rand->gettable_ctx_params != NULL)
174                 break;
175             rand->gettable_ctx_params =
176                 OSSL_get_OP_rand_gettable_ctx_params(fns);
177             break;
178         case OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS:
179             if (rand->settable_ctx_params != NULL)
180                 break;
181             rand->settable_ctx_params =
182                 OSSL_get_OP_rand_settable_ctx_params(fns);
183             break;
184         case OSSL_FUNC_RAND_GET_PARAMS:
185             if (rand->get_params != NULL)
186                 break;
187             rand->get_params = OSSL_get_OP_rand_get_params(fns);
188             break;
189         case OSSL_FUNC_RAND_GET_CTX_PARAMS:
190             if (rand->get_ctx_params != NULL)
191                 break;
192             rand->get_ctx_params = OSSL_get_OP_rand_get_ctx_params(fns);
193             break;
194         case OSSL_FUNC_RAND_SET_CTX_PARAMS:
195             if (rand->set_ctx_params != NULL)
196                 break;
197             rand->set_ctx_params = OSSL_get_OP_rand_set_ctx_params(fns);
198             break;
199         case OSSL_FUNC_RAND_VERIFY_ZEROIZATION:
200             if (rand->verify_zeroization != NULL)
201                 break;
202             rand->verify_zeroization = OSSL_get_OP_rand_verify_zeroization(fns);
203 #ifdef FIPS_MODULE
204             fnfipscnt++;
205 #endif
206             break;
207         }
208     }
209     if (fnrandcnt != 3
210             || fnctxcnt != 2
211 #ifdef FIPS_MODULE
212             || fnfipscnt != 1
213 #endif
214        ) {
215         /*
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.
220          */
221         evp_rand_free(rand);
222         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
223         return NULL;
224     }
225     rand->prov = prov;
226     if (prov != NULL)
227         ossl_provider_up_ref(prov);
228
229     return rand;
230 }
231
232 EVP_RAND *EVP_RAND_fetch(OPENSSL_CTX *libctx, const char *algorithm,
233                        const char *properties)
234 {
235     return evp_generic_fetch(libctx, OSSL_OP_RAND, algorithm, properties,
236                              evp_rand_from_dispatch, evp_rand_up_ref,
237                              evp_rand_free);
238 }
239
240 int EVP_RAND_up_ref(EVP_RAND *rand)
241 {
242     return evp_rand_up_ref(rand);
243 }
244
245 void EVP_RAND_free(EVP_RAND *rand)
246 {
247     evp_rand_free(rand);
248 }
249
250 int EVP_RAND_number(const EVP_RAND *rand)
251 {
252     return rand->name_id;
253 }
254
255 const char *EVP_RAND_name(const EVP_RAND *rand)
256 {
257     return evp_first_name(rand->prov, rand->name_id);
258 }
259
260 int EVP_RAND_is_a(const EVP_RAND *rand, const char *name)
261 {
262     return evp_is_a(rand->prov, rand->name_id, NULL, name);
263 }
264
265 const OSSL_PROVIDER *EVP_RAND_provider(const EVP_RAND *rand)
266 {
267     return rand->prov;
268 }
269
270 int EVP_RAND_get_params(EVP_RAND *rand, OSSL_PARAM params[])
271 {
272     if (rand->get_params != NULL)
273         return rand->get_params(params);
274     return 1;
275 }
276
277 EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, int secure, EVP_RAND_CTX *parent)
278 {
279     EVP_RAND_CTX *ctx;
280     void *parent_ctx = NULL;
281     const OSSL_DISPATCH *parent_dispatch = NULL;
282
283     if (rand == NULL)
284         return NULL;
285
286     ctx = OPENSSL_zalloc(sizeof(EVP_RAND_CTX));
287     if (ctx == NULL)
288         return NULL;
289     if (parent != NULL) {
290         EVP_RAND_CTX_enable_locking(parent);
291         parent_ctx = parent->data;
292         parent_dispatch = parent->meth->dispatch;
293     }
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);
299         OPENSSL_free(ctx);
300         return NULL;
301     }
302     ctx->meth = rand;
303     return ctx;
304 }
305
306 void EVP_RAND_CTX_free(EVP_RAND_CTX *ctx)
307 {
308     if (ctx != NULL) {
309         ctx->meth->freectx(ctx->data);
310         ctx->data = NULL;
311         EVP_RAND_CTX_free(ctx->parent);
312         EVP_RAND_free(ctx->meth);
313         OPENSSL_free(ctx);
314     }
315 }
316
317 EVP_RAND *EVP_RAND_CTX_rand(EVP_RAND_CTX *ctx)
318 {
319     return ctx->meth;
320 }
321
322 int EVP_RAND_CTX_get_params(EVP_RAND_CTX *ctx, OSSL_PARAM params[])
323 {
324     int res = 1;
325
326     if (ctx->meth->get_ctx_params != NULL) {
327         if (!evp_rand_lock(ctx))
328             return 0;
329         res = ctx->meth->get_ctx_params(ctx->data, params);
330         evp_rand_unlock(ctx);
331     }
332     return res;
333 }
334
335 int EVP_RAND_CTX_set_params(EVP_RAND_CTX *ctx, const OSSL_PARAM params[])
336 {
337     int res = 1;
338
339     if (ctx->meth->set_ctx_params != NULL) {
340         if (!evp_rand_lock(ctx))
341             return 0;
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 */
345         ctx->strength = 0;
346         ctx->max_request = 0;
347     }
348     return res;
349 }
350
351 const OSSL_PARAM *EVP_RAND_gettable_params(const EVP_RAND *rand)
352 {
353     if (rand->gettable_params == NULL)
354         return NULL;
355     return rand->gettable_params();
356 }
357
358 const OSSL_PARAM *EVP_RAND_gettable_ctx_params(const EVP_RAND *rand)
359 {
360     if (rand->gettable_ctx_params == NULL)
361         return NULL;
362     return rand->gettable_ctx_params();
363 }
364
365 const OSSL_PARAM *EVP_RAND_settable_ctx_params(const EVP_RAND *rand)
366 {
367     if (rand->settable_ctx_params == NULL)
368         return NULL;
369     return rand->settable_ctx_params();
370 }
371
372 void EVP_RAND_do_all_provided(OPENSSL_CTX *libctx,
373                               void (*fn)(EVP_RAND *rand, void *arg),
374                               void *arg)
375 {
376     evp_generic_do_all(libctx, OSSL_OP_RAND,
377                        (void (*)(void *, void *))fn, arg,
378                        evp_rand_from_dispatch, evp_rand_free);
379 }
380
381 void EVP_RAND_names_do_all(const EVP_RAND *rand,
382                            void (*fn)(const char *name, void *data),
383                            void *data)
384 {
385     if (rand->prov != NULL)
386         evp_names_do_all(rand->prov, rand->name_id, fn, data);
387 }
388
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)
392 {
393     int res;
394
395     if (!evp_rand_lock(ctx))
396         return 0;
397     res = ctx->meth->instantiate(ctx->data, strength, prediction_resistance,
398                                  pstr, pstr_len);
399     evp_rand_unlock(ctx);
400     return res;
401 }
402
403 int EVP_RAND_CTX_uninstantiate(EVP_RAND_CTX *ctx)
404 {
405     int res;
406
407     if (!evp_rand_lock(ctx))
408         return 0;
409     res = ctx->meth->uninstantiate(ctx->data);
410     evp_rand_unlock(ctx);
411     return res;
412 }
413
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)
417 {
418     size_t chunk;
419     OSSL_PARAM params[2];
420     int res = 0;
421
422     if (!evp_rand_lock(ctx))
423         return 0;
424     if (ctx->max_request == 0) {
425         params[0] = OSSL_PARAM_construct_size_t(OSSL_DRBG_PARAM_MAX_REQUEST,
426                                                 &ctx->max_request);
427         params[1] = OSSL_PARAM_construct_end();
428         if (!EVP_RAND_CTX_get_params(ctx, params)
429                 || ctx->max_request == 0)
430             goto err;
431     }
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))
436             goto err;
437     }
438     res = 1;
439 err:
440     evp_rand_unlock(ctx);
441     return res;
442 }
443
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)
447 {
448     int res = 1;
449
450     if (!evp_rand_lock(ctx))
451         return 0;
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);
456     return res;
457 }
458
459 int EVP_RAND_CTX_nonce(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen)
460 {
461     int res = 1;
462
463     if (!evp_rand_lock(ctx))
464         return 0;
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);
469     return res;
470 }
471
472 unsigned int EVP_RAND_CTX_strength(EVP_RAND_CTX *ctx)
473 {
474     OSSL_PARAM params[2];
475     int res;
476
477     if (ctx->strength == 0) {
478         params[0] = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH,
479                                               &ctx->strength);
480         params[1] = OSSL_PARAM_construct_end();
481         if (!evp_rand_lock(ctx))
482             return 0;
483         res = EVP_RAND_CTX_get_params(ctx, params);
484         evp_rand_unlock(ctx);
485         if (!res)
486             return 0;
487     }
488     return ctx->strength;
489 }
490
491 int EVP_RAND_CTX_state(EVP_RAND_CTX *ctx)
492 {
493     OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
494     int status, res;
495
496     params[0] = OSSL_PARAM_construct_int(OSSL_RAND_PARAM_STATE,
497                                          &status);
498     if (!evp_rand_lock(ctx))
499         return 0;
500     res = EVP_RAND_CTX_get_params(ctx, params);
501     evp_rand_unlock(ctx);
502     if (!res)
503         status = EVP_RAND_STATE_ERROR;
504     return status;
505 }
506
507 int EVP_RAND_CTX_verify_zeroization(EVP_RAND_CTX *ctx)
508 {
509     int res = 0;
510
511     if (ctx->meth->verify_zeroization != NULL) {
512         if (!evp_rand_lock(ctx))
513             return 0;
514         res = ctx->meth->verify_zeroization(ctx->data);
515         evp_rand_unlock(ctx);
516     }
517     return res;
518 }