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