apps/x509.c: Fix mem leaks in processing of -next_serial in print loop
[openssl.git] / providers / implementations / rands / test_rng.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 <string.h>
11 #include <openssl/core_dispatch.h>
12 #include <openssl/e_os2.h>
13 #include <openssl/params.h>
14 #include <openssl/core_names.h>
15 #include <openssl/evp.h>
16 #include <openssl/err.h>
17 #include <openssl/randerr.h>
18 #include "prov/providercommon.h"
19 #include "prov/provider_ctx.h"
20 #include "prov/provider_util.h"
21 #include "prov/implementations.h"
22
23 static OSSL_FUNC_rand_newctx_fn test_rng_new;
24 static OSSL_FUNC_rand_freectx_fn test_rng_free;
25 static OSSL_FUNC_rand_instantiate_fn test_rng_instantiate;
26 static OSSL_FUNC_rand_uninstantiate_fn test_rng_uninstantiate;
27 static OSSL_FUNC_rand_generate_fn test_rng_generate;
28 static OSSL_FUNC_rand_reseed_fn test_rng_reseed;
29 static OSSL_FUNC_rand_nonce_fn test_rng_nonce;
30 static OSSL_FUNC_rand_settable_ctx_params_fn test_rng_settable_ctx_params;
31 static OSSL_FUNC_rand_set_ctx_params_fn test_rng_set_ctx_params;
32 static OSSL_FUNC_rand_gettable_ctx_params_fn test_rng_gettable_ctx_params;
33 static OSSL_FUNC_rand_get_ctx_params_fn test_rng_get_ctx_params;
34 static OSSL_FUNC_rand_verify_zeroization_fn test_rng_verify_zeroization;
35 static OSSL_FUNC_rand_enable_locking_fn test_rng_enable_locking;
36 static OSSL_FUNC_rand_lock_fn test_rng_lock;
37 static OSSL_FUNC_rand_unlock_fn test_rng_unlock;
38
39 typedef struct {
40     void *provctx;
41     int state;
42     unsigned int strength;
43     size_t max_request;
44     unsigned char *entropy, *nonce;
45     size_t entropy_len, entropy_pos, nonce_len;
46     CRYPTO_RWLOCK *lock;
47 } PROV_TEST_RNG;
48
49 static void *test_rng_new(void *provctx, void *parent,
50                           const OSSL_DISPATCH *parent_dispatch)
51 {
52     PROV_TEST_RNG *t;
53
54     if (parent != NULL)
55         return NULL;
56
57     t = OPENSSL_zalloc(sizeof(*t));
58     if (t == NULL)
59         return NULL;
60
61     t->max_request = INT_MAX;
62     t->provctx = provctx;
63     t->state = EVP_RAND_STATE_UNINITIALISED;
64     return t;
65 }
66
67 static void test_rng_free(void *vtest)
68 {
69     PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
70
71     if (t == NULL)
72         return;
73     OPENSSL_free(t->entropy);
74     OPENSSL_free(t->nonce);
75     CRYPTO_THREAD_lock_free(t->lock);
76     OPENSSL_free(t);
77 }
78
79 static int test_rng_instantiate(void *vtest, unsigned int strength,
80                                 int prediction_resistance,
81                                 const unsigned char *pstr, size_t pstr_len)
82 {
83     PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
84
85     if (strength > t->strength)
86         return 0;
87
88     t->state = EVP_RAND_STATE_READY;
89     t->entropy_pos = 0;
90
91     return 1;
92 }
93
94 static int test_rng_uninstantiate(void *vtest)
95 {
96     PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
97
98     t->entropy_pos = 0;
99     t->state = EVP_RAND_STATE_UNINITIALISED;
100     return 1;
101 }
102
103 static int test_rng_generate(void *vtest, unsigned char *out, size_t outlen,
104                              unsigned int strength, int prediction_resistance,
105                              const unsigned char *adin, size_t adin_len)
106 {
107     PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
108     size_t i;
109
110     if (strength > t->strength)
111         return 0;
112
113     for (i = 0; i < outlen; i++) {
114         out[i] = t->entropy[t->entropy_pos++];
115         if (t->entropy_pos >= t->entropy_len)
116             break;
117     }
118     return 1;
119 }
120
121 static int test_rng_reseed(ossl_unused void *vtest,
122                            ossl_unused int prediction_resistance,
123                            ossl_unused const unsigned char *ent,
124                            ossl_unused size_t ent_len,
125                            ossl_unused const unsigned char *adin,
126                            ossl_unused size_t adin_len)
127 {
128     return 1;
129 }
130
131 static size_t test_rng_nonce(void *vtest, unsigned char *out,
132                              unsigned int strength,
133                              ossl_unused size_t min_noncelen,
134                              ossl_unused size_t max_noncelen)
135 {
136     PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
137
138     if (t->nonce == NULL || strength > t->strength)
139         return 0;
140
141     if (out != NULL)
142         memcpy(out, t->nonce, t->nonce_len);
143     return t->nonce_len;
144 }
145
146 static int test_rng_get_ctx_params(void *vtest, OSSL_PARAM params[])
147 {
148     PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
149     OSSL_PARAM *p;
150
151     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STATE);
152     if (p != NULL && !OSSL_PARAM_set_int(p, t->state))
153         return 0;
154
155     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STRENGTH);
156     if (p != NULL && !OSSL_PARAM_set_int(p, t->strength))
157         return 0;
158
159     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST);
160     if (p != NULL && !OSSL_PARAM_set_size_t(p, t->max_request))
161         return 0;
162     return 1;
163 }
164
165 static const OSSL_PARAM *test_rng_gettable_ctx_params(ossl_unused void *provctx)
166 {
167     static const OSSL_PARAM known_gettable_ctx_params[] = {
168         OSSL_PARAM_int(OSSL_RAND_PARAM_STATE, NULL),
169         OSSL_PARAM_uint(OSSL_RAND_PARAM_STRENGTH, NULL),
170         OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL),
171         OSSL_PARAM_END
172     };
173     return known_gettable_ctx_params;
174 }
175
176 static int test_rng_set_ctx_params(void *vtest, const OSSL_PARAM params[])
177 {
178     PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
179     const OSSL_PARAM *p;
180     void *ptr = NULL;
181     size_t size = 0;
182
183     p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_STRENGTH);
184     if (p != NULL && !OSSL_PARAM_get_uint(p, &t->strength))
185         return 0;
186
187     p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_TEST_ENTROPY);
188     if (p != NULL) {
189         if (!OSSL_PARAM_get_octet_string(p, &ptr, 0, &size))
190             return 0;
191         OPENSSL_free(t->entropy);
192         t->entropy = ptr;
193         t->entropy_len = size;
194         t->entropy_pos = 0;
195         ptr = NULL;
196     }
197
198     p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_TEST_NONCE);
199     if (p != NULL) {
200         if (!OSSL_PARAM_get_octet_string(p, &ptr, 0, &size))
201             return 0;
202         OPENSSL_free(t->nonce);
203         t->nonce = ptr;
204         t->nonce_len = size;
205     }
206
207     p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_MAX_REQUEST);
208     if (p != NULL  && !OSSL_PARAM_get_size_t(p, &t->max_request))
209         return 0;
210
211     return 1;
212 }
213
214 static const OSSL_PARAM *test_rng_settable_ctx_params(ossl_unused void *provctx)
215 {
216     static const OSSL_PARAM known_settable_ctx_params[] = {
217         OSSL_PARAM_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY, NULL, 0),
218         OSSL_PARAM_octet_string(OSSL_RAND_PARAM_TEST_NONCE, NULL, 0),
219         OSSL_PARAM_uint(OSSL_RAND_PARAM_STRENGTH, NULL),
220         OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL),
221         OSSL_PARAM_END
222     };
223     return known_settable_ctx_params;
224 }
225
226 static int test_rng_verify_zeroization(ossl_unused void *vtest)
227 {
228     return 1;
229 }
230
231 static int test_rng_enable_locking(void *vtest)
232 {
233     PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
234
235     if (t != NULL && t->lock == NULL) {
236         t->lock = CRYPTO_THREAD_lock_new();
237         if (t->lock == NULL) {
238             ERR_raise(ERR_LIB_PROV, RAND_R_FAILED_TO_CREATE_LOCK);
239             return 0;
240         }
241     }
242     return 1;
243 }
244
245 static int test_rng_lock(void *vtest)
246 {
247     PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
248
249     if (t == NULL || t->lock == NULL)
250         return 1;
251     return CRYPTO_THREAD_write_lock(t->lock);
252 }
253
254 static void test_rng_unlock(void *vtest)
255 {
256     PROV_TEST_RNG *t = (PROV_TEST_RNG *)vtest;
257
258     if (t != NULL && t->lock != NULL)
259         CRYPTO_THREAD_unlock(t->lock);
260 }
261
262 const OSSL_DISPATCH ossl_test_rng_functions[] = {
263     { OSSL_FUNC_RAND_NEWCTX, (void(*)(void))test_rng_new },
264     { OSSL_FUNC_RAND_FREECTX, (void(*)(void))test_rng_free },
265     { OSSL_FUNC_RAND_INSTANTIATE,
266       (void(*)(void))test_rng_instantiate },
267     { OSSL_FUNC_RAND_UNINSTANTIATE,
268       (void(*)(void))test_rng_uninstantiate },
269     { OSSL_FUNC_RAND_GENERATE, (void(*)(void))test_rng_generate },
270     { OSSL_FUNC_RAND_RESEED, (void(*)(void))test_rng_reseed },
271     { OSSL_FUNC_RAND_NONCE, (void(*)(void))test_rng_nonce },
272     { OSSL_FUNC_RAND_ENABLE_LOCKING, (void(*)(void))test_rng_enable_locking },
273     { OSSL_FUNC_RAND_LOCK, (void(*)(void))test_rng_lock },
274     { OSSL_FUNC_RAND_UNLOCK, (void(*)(void))test_rng_unlock },
275     { OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS,
276       (void(*)(void))test_rng_settable_ctx_params },
277     { OSSL_FUNC_RAND_SET_CTX_PARAMS, (void(*)(void))test_rng_set_ctx_params },
278     { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
279       (void(*)(void))test_rng_gettable_ctx_params },
280     { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))test_rng_get_ctx_params },
281     { OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
282       (void(*)(void))test_rng_verify_zeroization },
283     { 0, NULL }
284 };