Make the naming scheme for dispatched functions more consistent
[oweals/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 "prov/providercommon.h"
15 #include "prov/provider_ctx.h"
16 #include "prov/provider_util.h"
17 #include "prov/implementations.h"
18 #include "drbg_local.h"
19
20 static OSSL_FUNC_rand_newctx_fn test_rng_new_wrapper;
21 static OSSL_FUNC_rand_freectx_fn test_rng_free;
22 static OSSL_FUNC_rand_instantiate_fn test_rng_instantiate_wrapper;
23 static OSSL_FUNC_rand_uninstantiate_fn test_rng_uninstantiate_wrapper;
24 static OSSL_FUNC_rand_generate_fn test_rng_generate_wrapper;
25 static OSSL_FUNC_rand_reseed_fn test_rng_reseed_wrapper;
26 static OSSL_FUNC_rand_nonce_fn test_rng_nonce;
27 static OSSL_FUNC_rand_settable_ctx_params_fn test_rng_settable_ctx_params;
28 static OSSL_FUNC_rand_set_ctx_params_fn test_rng_set_ctx_params;
29 static OSSL_FUNC_rand_gettable_ctx_params_fn test_rng_gettable_ctx_params;
30 static OSSL_FUNC_rand_get_ctx_params_fn test_rng_get_ctx_params;
31 static OSSL_FUNC_rand_verify_zeroization_fn test_rng_verify_zeroization;
32
33 typedef struct {
34     unsigned char *entropy, *nonce;
35     size_t entropy_len, entropy_pos, nonce_len;
36     unsigned int strength;
37 } PROV_TEST_RNG;
38
39 static int test_rng_new(PROV_DRBG *ctx)
40 {
41     PROV_TEST_RNG *t;
42
43     t = OPENSSL_zalloc(sizeof(*t));
44     if (t == NULL)
45         return 0;
46     ctx->data = t;
47     ctx->seedlen = INT_MAX;
48     ctx->max_entropylen = INT_MAX;
49     ctx->max_noncelen = INT_MAX;
50     ctx->max_perslen = INT_MAX;
51     ctx->max_adinlen = INT_MAX;
52     ctx->max_request = INT_MAX;
53     return 1;
54 }
55
56 static void test_rng_free(void *vdrbg)
57 {
58     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
59     PROV_TEST_RNG *t = (PROV_TEST_RNG *)drbg->data;
60
61     OPENSSL_free(t->entropy);
62     OPENSSL_free(t->nonce);
63     OPENSSL_free(drbg->data);
64     prov_rand_drbg_free(drbg);
65 }
66
67 static int test_rng_instantiate(PROV_DRBG *drbg,
68                                 const unsigned char *ent, size_t ent_len,
69                                 const unsigned char *nonce, size_t nonce_len,
70                                 const unsigned char *pstr, size_t pstr_len)
71 {
72     PROV_TEST_RNG *t = (PROV_TEST_RNG *)drbg->data;
73
74     if (ent != NULL && (ent_len < drbg->min_entropylen
75                         || ent_len >= drbg->max_entropylen))
76         return 0;
77     if (nonce != NULL && (nonce_len < drbg->min_noncelen
78                         || nonce_len >= drbg->max_noncelen))
79         return 0;
80     if (pstr != NULL && pstr_len >= drbg->max_perslen)
81         return 0;
82
83     t->entropy_pos = 0;
84     return 1;
85 }
86
87 static int test_rng_instantiate_wrapper(void *vdrbg, unsigned int strength,
88                                         int prediction_resistance,
89                                         const unsigned char *pstr,
90                                         size_t pstr_len)
91 {
92     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
93
94     if (pstr != NULL && pstr_len >= drbg->max_perslen)
95         return 0;
96
97     return PROV_DRBG_instantiate(drbg, strength, prediction_resistance,
98                                  pstr, pstr_len);
99 }
100
101 static int test_rng_uninstantiate(PROV_DRBG *drbg)
102 {
103     PROV_TEST_RNG *t = (PROV_TEST_RNG *)drbg->data;
104
105     t->entropy_pos = 0;
106     return PROV_DRBG_uninstantiate(drbg);
107 }
108
109 static int test_rng_uninstantiate_wrapper(void *vdrbg)
110 {
111     return test_rng_uninstantiate((PROV_DRBG *)vdrbg);
112 }
113
114 static int test_rng_generate(PROV_DRBG *drbg,
115                              unsigned char *out, size_t outlen,
116                              const unsigned char *adin, size_t adin_len)
117 {
118     PROV_TEST_RNG *t = (PROV_TEST_RNG *)drbg->data;
119     size_t i;
120
121     if (t->entropy == NULL || (adin != NULL && adin_len >= drbg->max_adinlen))
122         return 0;
123
124     for (i = 0; i < outlen; i++) {
125         out[i] = t->entropy[t->entropy_pos++];
126         if (t->entropy_pos >= t->entropy_len)
127             break;
128     }
129     return 1;
130 }
131
132 static int test_rng_generate_wrapper
133     (void *vdrbg, unsigned char *out, size_t outlen,
134       unsigned int strength, int prediction_resistance,
135       const unsigned char *adin, size_t adin_len)
136 {
137     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
138
139     if (strength > drbg->strength)
140         return 0;
141     return test_rng_generate(drbg, out, outlen, adin, adin_len);
142 }
143
144 static int test_rng_reseed(PROV_DRBG *drbg,
145                             const unsigned char *ent, size_t ent_len,
146                             const unsigned char *adin, size_t adin_len)
147 {
148     if (ent != NULL && (ent_len < drbg->min_entropylen
149                         || ent_len >= drbg->max_entropylen))
150         return 0;
151     if (adin != NULL && adin_len >= drbg->max_adinlen)
152         return 0;
153
154     return 1;
155 }
156
157 static int test_rng_reseed_wrapper(void *vdrbg, int prediction_resistance,
158                                    const unsigned char *ent, size_t ent_len,
159                                    const unsigned char *adin, size_t adin_len)
160 {
161     return test_rng_reseed((PROV_DRBG *)vdrbg, ent, ent_len, adin, adin_len);
162 }
163
164 static size_t test_rng_nonce(void *vdrbg, unsigned char *out,
165                              unsigned int strength, size_t min_noncelen,
166                              size_t max_noncelen)
167 {
168     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
169     PROV_TEST_RNG *t = (PROV_TEST_RNG *)drbg->data;
170
171     if (t->nonce == NULL
172             || strength > drbg->strength
173             || min_noncelen > t->nonce_len
174             || max_noncelen < t->nonce_len)
175         return 0;
176
177     if (out != NULL)
178         memcpy(out, t->nonce, t->nonce_len);
179     return t->nonce_len;
180 }
181
182 static int test_rng_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
183 {
184     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
185
186     return drbg_get_ctx_params(drbg, params);
187 }
188
189 static const OSSL_PARAM *test_rng_gettable_ctx_params(void)
190 {
191     static const OSSL_PARAM known_gettable_ctx_params[] = {
192         OSSL_PARAM_DRBG_GETABLE_CTX_COMMON,
193         OSSL_PARAM_END
194     };
195     return known_gettable_ctx_params;
196 }
197
198 static int set_size_t(const OSSL_PARAM *params, const char *name,
199                             size_t *val)
200 {
201     const OSSL_PARAM *p = OSSL_PARAM_locate_const(params, name);
202
203     return p == NULL || OSSL_PARAM_get_size_t(p, val);
204 }
205
206 static int test_rng_set_ctx_params(void *vdrbg, const OSSL_PARAM params[])
207 {
208     PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
209     PROV_TEST_RNG *t = (PROV_TEST_RNG *)drbg->data;
210     const OSSL_PARAM *p;
211     void *ptr = NULL;
212     size_t size = 0;
213     unsigned int uint;
214
215     p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_STRENGTH);
216     if (p != NULL && !OSSL_PARAM_get_uint(p, &drbg->strength))
217         return 0;
218
219     p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_TEST_ENTROPY);
220     if (p != NULL) {
221         if (!OSSL_PARAM_get_octet_string(p, &ptr, 0, &size))
222             return 0;
223         OPENSSL_free(t->entropy);
224         t->entropy = ptr;
225         t->entropy_len = size;
226         t->entropy_pos = 0;
227         ptr = NULL;
228     }
229
230     p = OSSL_PARAM_locate_const(params, OSSL_RAND_PARAM_TEST_NONCE);
231     if (p != NULL) {
232         if (!OSSL_PARAM_get_octet_string(p, &ptr, 0, &size))
233             return 0;
234         OPENSSL_free(t->nonce);
235         t->nonce = ptr;
236         t->nonce_len = size;
237     }
238
239     p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_RESEED_CTR);
240     if (p != NULL) {
241         if (!OSSL_PARAM_get_uint(p, &uint))
242             return 0;
243         tsan_store(&drbg->reseed_counter, uint);
244     }
245
246     p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_RESEED_TIME);
247     if (p != NULL && !OSSL_PARAM_get_time_t(p, &drbg->reseed_time))
248         return 0;
249
250     if (!set_size_t(params, OSSL_DRBG_PARAM_MAX_REQUEST, &drbg->max_request)
251             || !set_size_t(params, OSSL_DRBG_PARAM_MIN_ENTROPYLEN,
252                            &drbg->min_entropylen)
253             || !set_size_t(params, OSSL_DRBG_PARAM_MAX_ENTROPYLEN,
254                            &drbg->max_entropylen)
255             || !set_size_t(params, OSSL_DRBG_PARAM_MIN_NONCELEN,
256                            &drbg->min_noncelen)
257             || !set_size_t(params, OSSL_DRBG_PARAM_MAX_NONCELEN,
258                            &drbg->max_noncelen)
259             || !set_size_t(params, OSSL_DRBG_PARAM_MAX_PERSLEN,
260                            &drbg->max_perslen)
261             || !set_size_t(params, OSSL_DRBG_PARAM_MAX_ADINLEN,
262                            &drbg->max_adinlen))
263         return 0;
264     return drbg_set_ctx_params(drbg, params);
265 }
266
267 static const OSSL_PARAM *test_rng_settable_ctx_params(void)
268 {
269     static const OSSL_PARAM known_settable_ctx_params[] = {
270         OSSL_PARAM_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY, NULL, 0),
271         OSSL_PARAM_octet_string(OSSL_RAND_PARAM_TEST_NONCE, NULL, 0),
272         OSSL_PARAM_uint(OSSL_RAND_PARAM_STRENGTH, NULL),
273         OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MAX_REQUEST, NULL),
274         OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MIN_ENTROPYLEN, NULL),
275         OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MAX_ENTROPYLEN, NULL),
276         OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MIN_NONCELEN, NULL),
277         OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MAX_NONCELEN, NULL),
278         OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MAX_PERSLEN, NULL),
279         OSSL_PARAM_size_t(OSSL_DRBG_PARAM_MAX_ADINLEN, NULL),
280         OSSL_PARAM_uint(OSSL_DRBG_PARAM_RESEED_CTR, NULL),
281         OSSL_PARAM_time_t(OSSL_DRBG_PARAM_RESEED_TIME, NULL),
282         OSSL_PARAM_DRBG_SETABLE_CTX_COMMON,
283         OSSL_PARAM_END
284     };
285     return known_settable_ctx_params;
286 }
287
288 static int test_rng_verify_zeroization(void *vdrbg)
289 {
290     return 1;
291 }
292
293 static void *test_rng_new_wrapper(void *provctx, void *parent,
294                                    const OSSL_DISPATCH *parent_dispatch)
295 {
296     return prov_rand_drbg_new(provctx, parent, parent_dispatch,
297                               &test_rng_new, &test_rng_instantiate,
298                               &test_rng_uninstantiate, &test_rng_reseed,
299                               &test_rng_generate);
300 }
301
302 const OSSL_DISPATCH test_rng_functions[] = {
303     { OSSL_FUNC_RAND_NEWCTX, (void(*)(void))test_rng_new_wrapper },
304     { OSSL_FUNC_RAND_FREECTX, (void(*)(void))test_rng_free },
305     { OSSL_FUNC_RAND_INSTANTIATE,
306       (void(*)(void))test_rng_instantiate_wrapper },
307     { OSSL_FUNC_RAND_UNINSTANTIATE,
308       (void(*)(void))test_rng_uninstantiate_wrapper },
309     { OSSL_FUNC_RAND_GENERATE, (void(*)(void))test_rng_generate_wrapper },
310     { OSSL_FUNC_RAND_RESEED, (void(*)(void))test_rng_reseed_wrapper },
311     { OSSL_FUNC_RAND_NONCE, (void(*)(void))test_rng_nonce },
312     { OSSL_FUNC_RAND_ENABLE_LOCKING, (void(*)(void))drbg_enable_locking },
313     { OSSL_FUNC_RAND_LOCK, (void(*)(void))drbg_lock },
314     { OSSL_FUNC_RAND_UNLOCK, (void(*)(void))drbg_unlock },
315     { OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS,
316       (void(*)(void))test_rng_settable_ctx_params },
317     { OSSL_FUNC_RAND_SET_CTX_PARAMS, (void(*)(void))test_rng_set_ctx_params },
318     { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
319       (void(*)(void))test_rng_gettable_ctx_params },
320     { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))test_rng_get_ctx_params },
321     { OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
322       (void(*)(void))test_rng_verify_zeroization },
323     { 0, NULL }
324 };