rand: core APIs for provider friendly random.
[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
62     rand->refcnt = 1;
63
64     return rand;
65 }
66
67 static void *evp_rand_from_dispatch(int name_id,
68                                     const OSSL_DISPATCH *fns,
69                                     OSSL_PROVIDER *prov)
70 {
71     EVP_RAND *rand = NULL;
72     int fnrandcnt = 0, fnctxcnt = 0;
73
74     if ((rand = evp_rand_new()) == NULL) {
75         EVPerr(0, ERR_R_MALLOC_FAILURE);
76         return NULL;
77     }
78     rand->name_id = name_id;
79     rand->dispatch = fns;
80     for (; fns->function_id != 0; fns++) {
81         switch (fns->function_id) {
82         case OSSL_FUNC_RAND_NEWCTX:
83             if (rand->newctx != NULL)
84                 break;
85             rand->newctx = OSSL_get_OP_rand_newctx(fns);
86             fnctxcnt++;
87             break;
88         case OSSL_FUNC_RAND_FREECTX:
89             if (rand->freectx != NULL)
90                 break;
91             rand->freectx = OSSL_get_OP_rand_freectx(fns);
92             fnctxcnt++;
93             break;
94         case OSSL_FUNC_RAND_INSTANTIATE:
95             if (rand->instantiate != NULL)
96                 break;
97             rand->instantiate = OSSL_get_OP_rand_instantiate(fns);
98             fnrandcnt++;
99             break;
100         case OSSL_FUNC_RAND_UNINSTANTIATE:
101              if (rand->uninstantiate != NULL)
102                 break;
103             rand->uninstantiate = OSSL_get_OP_rand_uninstantiate(fns);
104             fnrandcnt++;
105             break;
106         case OSSL_FUNC_RAND_GENERATE:
107             if (rand->generate != NULL)
108                 break;
109             rand->generate = OSSL_get_OP_rand_generate(fns);
110             fnrandcnt++;
111             break;
112         case OSSL_FUNC_RAND_RESEED:
113             if (rand->reseed != NULL)
114                 break;
115             rand->reseed = OSSL_get_OP_rand_reseed(fns);
116             break;
117         case OSSL_FUNC_RAND_NONCE:
118             if (rand->nonce != NULL)
119                 break;
120             rand->nonce = OSSL_get_OP_rand_nonce(fns);
121             break;
122         case OSSL_FUNC_RAND_SET_CALLBACKS:
123             if (rand->set_callbacks != NULL)
124                 break;
125             rand->set_callbacks = OSSL_get_OP_rand_set_callbacks(fns);
126             break;
127         case OSSL_FUNC_RAND_ENABLE_LOCKING:
128             if (rand->enable_prov_locking != NULL)
129                 break;
130             rand->enable_prov_locking = OSSL_get_OP_rand_enable_locking(fns);
131             break;
132         case OSSL_FUNC_RAND_LOCK:
133             if (rand->prov_lock != NULL)
134                 break;
135             rand->prov_lock = OSSL_get_OP_rand_lock(fns);
136             break;
137         case OSSL_FUNC_RAND_UNLOCK:
138             if (rand->prov_unlock != NULL)
139                 break;
140             rand->prov_unlock = OSSL_get_OP_rand_unlock(fns);
141             break;
142         case OSSL_FUNC_RAND_GETTABLE_PARAMS:
143             if (rand->gettable_params != NULL)
144                 break;
145             rand->gettable_params =
146                 OSSL_get_OP_rand_gettable_params(fns);
147             break;
148         case OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS:
149             if (rand->gettable_ctx_params != NULL)
150                 break;
151             rand->gettable_ctx_params =
152                 OSSL_get_OP_rand_gettable_ctx_params(fns);
153             break;
154         case OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS:
155             if (rand->settable_ctx_params != NULL)
156                 break;
157             rand->settable_ctx_params =
158                 OSSL_get_OP_rand_settable_ctx_params(fns);
159             break;
160         case OSSL_FUNC_RAND_GET_PARAMS:
161             if (rand->get_params != NULL)
162                 break;
163             rand->get_params = OSSL_get_OP_rand_get_params(fns);
164             break;
165         case OSSL_FUNC_RAND_GET_CTX_PARAMS:
166             if (rand->get_ctx_params != NULL)
167                 break;
168             rand->get_ctx_params = OSSL_get_OP_rand_get_ctx_params(fns);
169             break;
170         case OSSL_FUNC_RAND_SET_CTX_PARAMS:
171             if (rand->set_ctx_params != NULL)
172                 break;
173             rand->set_ctx_params = OSSL_get_OP_rand_set_ctx_params(fns);
174             break;
175         }
176     }
177     if (fnrandcnt != 3 || fnctxcnt != 2) {
178         /*
179          * In order to be a consistent set of functions we must have at least
180          * a complete set of "rand" functions and a complete set of context
181          * management functions.
182          */
183         evp_rand_free(rand);
184         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
185         return NULL;
186     }
187     rand->prov = prov;
188     if (prov != NULL)
189         ossl_provider_up_ref(prov);
190
191     return rand;
192 }
193
194 EVP_RAND *EVP_RAND_fetch(OPENSSL_CTX *libctx, const char *algorithm,
195                        const char *properties)
196 {
197     return evp_generic_fetch(libctx, OSSL_OP_RAND, algorithm, properties,
198                              evp_rand_from_dispatch, evp_rand_up_ref,
199                              evp_rand_free);
200 }
201
202 int EVP_RAND_up_ref(EVP_RAND *rand)
203 {
204     return evp_rand_up_ref(rand);
205 }
206
207 void EVP_RAND_free(EVP_RAND *rand)
208 {
209     evp_rand_free(rand);
210 }
211
212 int EVP_RAND_number(const EVP_RAND *rand)
213 {
214     return rand->name_id;
215 }
216
217 const char *EVP_RAND_name(const EVP_RAND *rand)
218 {
219     return evp_first_name(rand->prov, rand->name_id);
220 }
221
222 int EVP_RAND_is_a(const EVP_RAND *rand, const char *name)
223 {
224     return evp_is_a(rand->prov, rand->name_id, NULL, name);
225 }
226
227 const OSSL_PROVIDER *EVP_RAND_provider(const EVP_RAND *rand)
228 {
229     return rand->prov;
230 }
231
232 int EVP_RAND_get_params(EVP_RAND *rand, OSSL_PARAM params[])
233 {
234     if (rand->get_params != NULL)
235         return rand->get_params(params);
236     return 1;
237 }
238
239 EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, int secure, unsigned int df,
240                                EVP_RAND_CTX *parent)
241 {
242     EVP_RAND_CTX *ctx;
243     void *parent_ctx = NULL;
244     const OSSL_DISPATCH *parent_dispatch = NULL;
245
246     if (rand == NULL)
247         return NULL;
248
249     ctx = OPENSSL_zalloc(sizeof(EVP_RAND_CTX));
250     if (ctx == NULL)
251         return NULL;
252     if (parent != NULL) {
253         parent_ctx = parent->data;
254         parent_dispatch = parent->meth->dispatch;
255     }
256     if ((ctx->data = rand->newctx(ossl_provider_ctx(rand->prov), secure, df,
257                                   parent_ctx, parent_dispatch)) == NULL
258             || !EVP_RAND_up_ref(rand)) {
259         EVPerr(0, ERR_R_MALLOC_FAILURE);
260         rand->freectx(ctx->data);
261         OPENSSL_free(ctx);
262         return NULL;
263     }
264     ctx->meth = rand;
265     return ctx;
266 }
267
268 void EVP_RAND_CTX_free(EVP_RAND_CTX *ctx)
269 {
270     if (ctx != NULL) {
271         ctx->meth->freectx(ctx->data);
272         ctx->data = NULL;
273         EVP_RAND_CTX_free(ctx->parent);
274         EVP_RAND_free(ctx->meth);
275         OPENSSL_free(ctx);
276     }
277 }
278
279 EVP_RAND *EVP_RAND_CTX_rand(EVP_RAND_CTX *ctx)
280 {
281     return ctx->meth;
282 }
283
284 int EVP_RAND_CTX_get_params(EVP_RAND_CTX *ctx, OSSL_PARAM params[])
285 {
286     if (ctx->meth->get_ctx_params != NULL)
287         return ctx->meth->get_ctx_params(ctx->data, params);
288     return 1;
289 }
290
291 int EVP_RAND_CTX_set_params(EVP_RAND_CTX *ctx, const OSSL_PARAM params[])
292 {
293     if (ctx->meth->set_ctx_params != NULL)
294         return ctx->meth->set_ctx_params(ctx->data, params);
295     return 1;
296 }
297
298 const OSSL_PARAM *EVP_RAND_gettable_params(const EVP_RAND *rand)
299 {
300     if (rand->gettable_params == NULL)
301         return NULL;
302     return rand->gettable_params();
303 }
304
305 const OSSL_PARAM *EVP_RAND_gettable_ctx_params(const EVP_RAND *rand)
306 {
307     if (rand->gettable_ctx_params == NULL)
308         return NULL;
309     return rand->gettable_ctx_params();
310 }
311
312 const OSSL_PARAM *EVP_RAND_settable_ctx_params(const EVP_RAND *rand)
313 {
314     if (rand->settable_ctx_params == NULL)
315         return NULL;
316     return rand->settable_ctx_params();
317 }
318
319 void EVP_RAND_do_all_provided(OPENSSL_CTX *libctx,
320                               void (*fn)(EVP_RAND *rand, void *arg),
321                               void *arg)
322 {
323     evp_generic_do_all(libctx, OSSL_OP_RAND,
324                        (void (*)(void *, void *))fn, arg,
325                        evp_rand_from_dispatch, evp_rand_free);
326 }
327
328 void EVP_RAND_names_do_all(const EVP_RAND *rand,
329                            void (*fn)(const char *name, void *data),
330                            void *data)
331 {
332     if (rand->prov != NULL)
333         evp_names_do_all(rand->prov, rand->name_id, fn, data);
334 }
335
336 int EVP_RAND_CTX_instantiate(EVP_RAND_CTX *ctx, int strength,
337                              int prediction_resistance,
338                              const unsigned char *pstr, size_t pstr_len)
339 {
340     return ctx->meth->instantiate(ctx->data, strength, prediction_resistance,
341                                   pstr, pstr_len);
342 }
343
344 int EVP_RAND_CTX_uninstantiate(EVP_RAND_CTX *ctx)
345 {
346     return ctx->meth->uninstantiate(ctx->data);
347 }
348
349 int EVP_RAND_CTX_generate(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen,
350                           int strength, int prediction_resistance,
351                           const unsigned char *addin, size_t addin_len)
352 {
353     return ctx->meth->generate(ctx->data, out, outlen, strength,
354                                prediction_resistance, addin, addin_len);
355 }
356
357 int EVP_RAND_CTX_reseed(EVP_RAND_CTX *ctx, int prediction_resistance,
358                         const unsigned char *addin, size_t addin_len)
359 {
360     if (ctx->meth->reseed == NULL)
361         return 1;
362     return ctx->meth->reseed(ctx->data, prediction_resistance,
363                              addin, addin_len);
364 }
365
366 int EVP_RAND_CTX_nonce(EVP_RAND_CTX *ctx, unsigned char *out, size_t outlen)
367 {
368     if (ctx->meth->nonce != NULL)
369         return ctx->meth->nonce(ctx->data, out, outlen);
370     return ctx->meth->generate(ctx->data, out, outlen, 0, 0, NULL, 0);
371 }
372
373 int EVP_RAND_CTX_set_callbacks(const EVP_RAND_CTX *ctx,
374                                OSSL_CALLBACK *get_entropy,
375                                OSSL_CALLBACK *cleanup_entropy,
376                                OSSL_CALLBACK *get_nonce,
377                                OSSL_CALLBACK *cleanup_nonce)
378 {
379     if (ctx->meth->set_callbacks == NULL)
380         return 0;
381     return ctx->meth->set_callbacks(ctx->data, get_entropy, cleanup_entropy,
382                                     get_nonce, cleanup_nonce);
383 }
384