1 | /*
|
---|
2 | * Copyright 2011-2022 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/crypto.h>
|
---|
12 | #include <openssl/err.h>
|
---|
13 | #include <openssl/rand.h>
|
---|
14 | #include <openssl/evp.h>
|
---|
15 | #include "crypto/rand.h"
|
---|
16 | #include <openssl/proverr.h>
|
---|
17 | #include "drbg_local.h"
|
---|
18 | #include "internal/thread_once.h"
|
---|
19 | #include "crypto/cryptlib.h"
|
---|
20 | #include "prov/seeding.h"
|
---|
21 | #include "crypto/rand_pool.h"
|
---|
22 | #include "prov/provider_ctx.h"
|
---|
23 | #include "prov/providercommon.h"
|
---|
24 | #include "crypto/context.h"
|
---|
25 |
|
---|
26 | /*
|
---|
27 | * Support framework for NIST SP 800-90A DRBG
|
---|
28 | *
|
---|
29 | * See manual page PROV_DRBG(7) for a general overview.
|
---|
30 | *
|
---|
31 | * The OpenSSL model is to have new and free functions, and that new
|
---|
32 | * does all initialization. That is not the NIST model, which has
|
---|
33 | * instantiation and un-instantiate, and re-use within a new/free
|
---|
34 | * lifecycle. (No doubt this comes from the desire to support hardware
|
---|
35 | * DRBG, where allocation of resources on something like an HSM is
|
---|
36 | * a much bigger deal than just re-setting an allocated resource.)
|
---|
37 | */
|
---|
38 |
|
---|
39 | /* NIST SP 800-90A DRBG recommends the use of a personalization string. */
|
---|
40 | static const char ossl_pers_string[] = DRBG_DEFAULT_PERS_STRING;
|
---|
41 |
|
---|
42 | static const OSSL_DISPATCH *find_call(const OSSL_DISPATCH *dispatch,
|
---|
43 | int function);
|
---|
44 |
|
---|
45 | static int rand_drbg_restart(PROV_DRBG *drbg);
|
---|
46 |
|
---|
47 | int ossl_drbg_lock(void *vctx)
|
---|
48 | {
|
---|
49 | PROV_DRBG *drbg = vctx;
|
---|
50 |
|
---|
51 | if (drbg == NULL || drbg->lock == NULL)
|
---|
52 | return 1;
|
---|
53 | return CRYPTO_THREAD_write_lock(drbg->lock);
|
---|
54 | }
|
---|
55 |
|
---|
56 | void ossl_drbg_unlock(void *vctx)
|
---|
57 | {
|
---|
58 | PROV_DRBG *drbg = vctx;
|
---|
59 |
|
---|
60 | if (drbg != NULL && drbg->lock != NULL)
|
---|
61 | CRYPTO_THREAD_unlock(drbg->lock);
|
---|
62 | }
|
---|
63 |
|
---|
64 | static int ossl_drbg_lock_parent(PROV_DRBG *drbg)
|
---|
65 | {
|
---|
66 | void *parent = drbg->parent;
|
---|
67 |
|
---|
68 | if (parent != NULL
|
---|
69 | && drbg->parent_lock != NULL
|
---|
70 | && !drbg->parent_lock(parent)) {
|
---|
71 | ERR_raise(ERR_LIB_PROV, PROV_R_PARENT_LOCKING_NOT_ENABLED);
|
---|
72 | return 0;
|
---|
73 | }
|
---|
74 | return 1;
|
---|
75 | }
|
---|
76 |
|
---|
77 | static void ossl_drbg_unlock_parent(PROV_DRBG *drbg)
|
---|
78 | {
|
---|
79 | void *parent = drbg->parent;
|
---|
80 |
|
---|
81 | if (parent != NULL && drbg->parent_unlock != NULL)
|
---|
82 | drbg->parent_unlock(parent);
|
---|
83 | }
|
---|
84 |
|
---|
85 | static int get_parent_strength(PROV_DRBG *drbg, unsigned int *str)
|
---|
86 | {
|
---|
87 | OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
---|
88 | void *parent = drbg->parent;
|
---|
89 | int res;
|
---|
90 |
|
---|
91 | if (drbg->parent_get_ctx_params == NULL) {
|
---|
92 | ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_GET_PARENT_STRENGTH);
|
---|
93 | return 0;
|
---|
94 | }
|
---|
95 |
|
---|
96 | *params = OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH, str);
|
---|
97 | if (!ossl_drbg_lock_parent(drbg)) {
|
---|
98 | ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_LOCK_PARENT);
|
---|
99 | return 0;
|
---|
100 | }
|
---|
101 | res = drbg->parent_get_ctx_params(parent, params);
|
---|
102 | ossl_drbg_unlock_parent(drbg);
|
---|
103 | if (!res) {
|
---|
104 | ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_GET_PARENT_STRENGTH);
|
---|
105 | return 0;
|
---|
106 | }
|
---|
107 | return 1;
|
---|
108 | }
|
---|
109 |
|
---|
110 | static unsigned int get_parent_reseed_count(PROV_DRBG *drbg)
|
---|
111 | {
|
---|
112 | OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
---|
113 | void *parent = drbg->parent;
|
---|
114 | unsigned int r = 0;
|
---|
115 |
|
---|
116 | *params = OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_COUNTER, &r);
|
---|
117 | if (!ossl_drbg_lock_parent(drbg)) {
|
---|
118 | ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_LOCK_PARENT);
|
---|
119 | goto err;
|
---|
120 | }
|
---|
121 | if (!drbg->parent_get_ctx_params(parent, params))
|
---|
122 | r = 0;
|
---|
123 | ossl_drbg_unlock_parent(drbg);
|
---|
124 | return r;
|
---|
125 |
|
---|
126 | err:
|
---|
127 | r = tsan_load(&drbg->reseed_counter) - 2;
|
---|
128 | if (r == 0)
|
---|
129 | r = UINT_MAX;
|
---|
130 | return r;
|
---|
131 | }
|
---|
132 |
|
---|
133 | /*
|
---|
134 | * Implements the get_entropy() callback
|
---|
135 | *
|
---|
136 | * If the DRBG has a parent, then the required amount of entropy input
|
---|
137 | * is fetched using the parent's ossl_prov_drbg_generate().
|
---|
138 | *
|
---|
139 | * Otherwise, the entropy is polled from the system entropy sources
|
---|
140 | * using ossl_pool_acquire_entropy().
|
---|
141 | *
|
---|
142 | * If a random pool has been added to the DRBG using RAND_add(), then
|
---|
143 | * its entropy will be used up first.
|
---|
144 | */
|
---|
145 | size_t ossl_drbg_get_seed(void *vdrbg, unsigned char **pout,
|
---|
146 | int entropy, size_t min_len,
|
---|
147 | size_t max_len, int prediction_resistance,
|
---|
148 | const unsigned char *adin, size_t adin_len)
|
---|
149 | {
|
---|
150 | PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
|
---|
151 | size_t bytes_needed;
|
---|
152 | unsigned char *buffer;
|
---|
153 |
|
---|
154 | /* Figure out how many bytes we need */
|
---|
155 | bytes_needed = entropy >= 0 ? (entropy + 7) / 8 : 0;
|
---|
156 | if (bytes_needed < min_len)
|
---|
157 | bytes_needed = min_len;
|
---|
158 | if (bytes_needed > max_len)
|
---|
159 | bytes_needed = max_len;
|
---|
160 |
|
---|
161 | /* Allocate storage */
|
---|
162 | buffer = OPENSSL_secure_malloc(bytes_needed);
|
---|
163 | if (buffer == NULL) {
|
---|
164 | ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
|
---|
165 | return 0;
|
---|
166 | }
|
---|
167 |
|
---|
168 | /*
|
---|
169 | * Get random data. Include our DRBG address as
|
---|
170 | * additional input, in order to provide a distinction between
|
---|
171 | * different DRBG child instances.
|
---|
172 | *
|
---|
173 | * Note: using the sizeof() operator on a pointer triggers
|
---|
174 | * a warning in some static code analyzers, but it's
|
---|
175 | * intentional and correct here.
|
---|
176 | */
|
---|
177 | if (!ossl_prov_drbg_generate(drbg, buffer, bytes_needed,
|
---|
178 | drbg->strength, prediction_resistance,
|
---|
179 | (unsigned char *)&drbg, sizeof(drbg))) {
|
---|
180 | OPENSSL_secure_clear_free(buffer, bytes_needed);
|
---|
181 | ERR_raise(ERR_LIB_PROV, PROV_R_GENERATE_ERROR);
|
---|
182 | return 0;
|
---|
183 | }
|
---|
184 | *pout = buffer;
|
---|
185 | return bytes_needed;
|
---|
186 | }
|
---|
187 |
|
---|
188 | /* Implements the cleanup_entropy() callback */
|
---|
189 | void ossl_drbg_clear_seed(ossl_unused void *vdrbg,
|
---|
190 | unsigned char *out, size_t outlen)
|
---|
191 | {
|
---|
192 | OPENSSL_secure_clear_free(out, outlen);
|
---|
193 | }
|
---|
194 |
|
---|
195 | static size_t get_entropy(PROV_DRBG *drbg, unsigned char **pout, int entropy,
|
---|
196 | size_t min_len, size_t max_len,
|
---|
197 | int prediction_resistance)
|
---|
198 | {
|
---|
199 | size_t bytes;
|
---|
200 | unsigned int p_str;
|
---|
201 |
|
---|
202 | if (drbg->parent == NULL)
|
---|
203 | #ifdef FIPS_MODULE
|
---|
204 | return ossl_crngt_get_entropy(drbg, pout, entropy, min_len, max_len,
|
---|
205 | prediction_resistance);
|
---|
206 | #else
|
---|
207 | return ossl_prov_get_entropy(drbg->provctx, pout, entropy, min_len,
|
---|
208 | max_len);
|
---|
209 | #endif
|
---|
210 |
|
---|
211 | if (drbg->parent_get_seed == NULL) {
|
---|
212 | ERR_raise(ERR_LIB_PROV, PROV_R_PARENT_CANNOT_SUPPLY_ENTROPY_SEED);
|
---|
213 | return 0;
|
---|
214 | }
|
---|
215 | if (!get_parent_strength(drbg, &p_str))
|
---|
216 | return 0;
|
---|
217 | if (drbg->strength > p_str) {
|
---|
218 | /*
|
---|
219 | * We currently don't support the algorithm from NIST SP 800-90C
|
---|
220 | * 10.1.2 to use a weaker DRBG as source
|
---|
221 | */
|
---|
222 | ERR_raise(ERR_LIB_PROV, PROV_R_PARENT_STRENGTH_TOO_WEAK);
|
---|
223 | return 0;
|
---|
224 | }
|
---|
225 |
|
---|
226 | /*
|
---|
227 | * Our lock is already held, but we need to lock our parent before
|
---|
228 | * generating bits from it. Note: taking the lock will be a no-op
|
---|
229 | * if locking is not required (while drbg->parent->lock == NULL).
|
---|
230 | */
|
---|
231 | if (!ossl_drbg_lock_parent(drbg))
|
---|
232 | return 0;
|
---|
233 | /*
|
---|
234 | * Get random data from parent. Include our DRBG address as
|
---|
235 | * additional input, in order to provide a distinction between
|
---|
236 | * different DRBG child instances.
|
---|
237 | *
|
---|
238 | * Note: using the sizeof() operator on a pointer triggers
|
---|
239 | * a warning in some static code analyzers, but it's
|
---|
240 | * intentional and correct here.
|
---|
241 | */
|
---|
242 | bytes = drbg->parent_get_seed(drbg->parent, pout, drbg->strength,
|
---|
243 | min_len, max_len, prediction_resistance,
|
---|
244 | (unsigned char *)&drbg, sizeof(drbg));
|
---|
245 | ossl_drbg_unlock_parent(drbg);
|
---|
246 | return bytes;
|
---|
247 | }
|
---|
248 |
|
---|
249 | static void cleanup_entropy(PROV_DRBG *drbg, unsigned char *out, size_t outlen)
|
---|
250 | {
|
---|
251 | if (drbg->parent == NULL) {
|
---|
252 | #ifdef FIPS_MODULE
|
---|
253 | ossl_crngt_cleanup_entropy(drbg, out, outlen);
|
---|
254 | #else
|
---|
255 | ossl_prov_cleanup_entropy(drbg->provctx, out, outlen);
|
---|
256 | #endif
|
---|
257 | } else if (drbg->parent_clear_seed != NULL) {
|
---|
258 | if (!ossl_drbg_lock_parent(drbg))
|
---|
259 | return;
|
---|
260 | drbg->parent_clear_seed(drbg, out, outlen);
|
---|
261 | ossl_drbg_unlock_parent(drbg);
|
---|
262 | }
|
---|
263 | }
|
---|
264 |
|
---|
265 | #ifndef PROV_RAND_GET_RANDOM_NONCE
|
---|
266 | typedef struct prov_drbg_nonce_global_st {
|
---|
267 | CRYPTO_RWLOCK *rand_nonce_lock;
|
---|
268 | int rand_nonce_count;
|
---|
269 | } PROV_DRBG_NONCE_GLOBAL;
|
---|
270 |
|
---|
271 | /*
|
---|
272 | * drbg_ossl_ctx_new() calls drgb_setup() which calls rand_drbg_get_nonce()
|
---|
273 | * which needs to get the rand_nonce_lock out of the OSSL_LIB_CTX...but since
|
---|
274 | * drbg_ossl_ctx_new() hasn't finished running yet we need the rand_nonce_lock
|
---|
275 | * to be in a different global data object. Otherwise we will go into an
|
---|
276 | * infinite recursion loop.
|
---|
277 | */
|
---|
278 | void *ossl_prov_drbg_nonce_ctx_new(OSSL_LIB_CTX *libctx)
|
---|
279 | {
|
---|
280 | PROV_DRBG_NONCE_GLOBAL *dngbl = OPENSSL_zalloc(sizeof(*dngbl));
|
---|
281 |
|
---|
282 | if (dngbl == NULL)
|
---|
283 | return NULL;
|
---|
284 |
|
---|
285 | dngbl->rand_nonce_lock = CRYPTO_THREAD_lock_new();
|
---|
286 | if (dngbl->rand_nonce_lock == NULL) {
|
---|
287 | OPENSSL_free(dngbl);
|
---|
288 | return NULL;
|
---|
289 | }
|
---|
290 |
|
---|
291 | return dngbl;
|
---|
292 | }
|
---|
293 |
|
---|
294 | void ossl_prov_drbg_nonce_ctx_free(void *vdngbl)
|
---|
295 | {
|
---|
296 | PROV_DRBG_NONCE_GLOBAL *dngbl = vdngbl;
|
---|
297 |
|
---|
298 | if (dngbl == NULL)
|
---|
299 | return;
|
---|
300 |
|
---|
301 | CRYPTO_THREAD_lock_free(dngbl->rand_nonce_lock);
|
---|
302 |
|
---|
303 | OPENSSL_free(dngbl);
|
---|
304 | }
|
---|
305 |
|
---|
306 | /* Get a nonce from the operating system */
|
---|
307 | static size_t prov_drbg_get_nonce(PROV_DRBG *drbg, unsigned char **pout,
|
---|
308 | size_t min_len, size_t max_len)
|
---|
309 | {
|
---|
310 | size_t ret = 0, n;
|
---|
311 | unsigned char *buf = NULL;
|
---|
312 | OSSL_LIB_CTX *libctx = ossl_prov_ctx_get0_libctx(drbg->provctx);
|
---|
313 | PROV_DRBG_NONCE_GLOBAL *dngbl
|
---|
314 | = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DRBG_NONCE_INDEX);
|
---|
315 | struct {
|
---|
316 | void *drbg;
|
---|
317 | int count;
|
---|
318 | } data;
|
---|
319 |
|
---|
320 | if (dngbl == NULL)
|
---|
321 | return 0;
|
---|
322 |
|
---|
323 | if (drbg->parent != NULL && drbg->parent_nonce != NULL) {
|
---|
324 | n = drbg->parent_nonce(drbg->parent, NULL, 0, drbg->min_noncelen,
|
---|
325 | drbg->max_noncelen);
|
---|
326 | if (n > 0 && (buf = OPENSSL_malloc(n)) != NULL) {
|
---|
327 | ret = drbg->parent_nonce(drbg->parent, buf, 0,
|
---|
328 | drbg->min_noncelen, drbg->max_noncelen);
|
---|
329 | if (ret == n) {
|
---|
330 | *pout = buf;
|
---|
331 | return ret;
|
---|
332 | }
|
---|
333 | OPENSSL_free(buf);
|
---|
334 | }
|
---|
335 | }
|
---|
336 |
|
---|
337 | /* Use the built in nonce source plus some of our specifics */
|
---|
338 | memset(&data, 0, sizeof(data));
|
---|
339 | data.drbg = drbg;
|
---|
340 | CRYPTO_atomic_add(&dngbl->rand_nonce_count, 1, &data.count,
|
---|
341 | dngbl->rand_nonce_lock);
|
---|
342 | return ossl_prov_get_nonce(drbg->provctx, pout, min_len, max_len,
|
---|
343 | &data, sizeof(data));
|
---|
344 | }
|
---|
345 | #endif /* PROV_RAND_GET_RANDOM_NONCE */
|
---|
346 |
|
---|
347 | /*
|
---|
348 | * Instantiate |drbg|, after it has been initialized. Use |pers| and
|
---|
349 | * |perslen| as prediction-resistance input.
|
---|
350 | *
|
---|
351 | * Requires that drbg->lock is already locked for write, if non-null.
|
---|
352 | *
|
---|
353 | * Returns 1 on success, 0 on failure.
|
---|
354 | */
|
---|
355 | int ossl_prov_drbg_instantiate(PROV_DRBG *drbg, unsigned int strength,
|
---|
356 | int prediction_resistance,
|
---|
357 | const unsigned char *pers, size_t perslen)
|
---|
358 | {
|
---|
359 | unsigned char *nonce = NULL, *entropy = NULL;
|
---|
360 | size_t noncelen = 0, entropylen = 0;
|
---|
361 | size_t min_entropy, min_entropylen, max_entropylen;
|
---|
362 |
|
---|
363 | if (strength > drbg->strength) {
|
---|
364 | ERR_raise(ERR_LIB_PROV, PROV_R_INSUFFICIENT_DRBG_STRENGTH);
|
---|
365 | goto end;
|
---|
366 | }
|
---|
367 | min_entropy = drbg->strength;
|
---|
368 | min_entropylen = drbg->min_entropylen;
|
---|
369 | max_entropylen = drbg->max_entropylen;
|
---|
370 |
|
---|
371 | if (pers == NULL) {
|
---|
372 | pers = (const unsigned char *)ossl_pers_string;
|
---|
373 | perslen = sizeof(ossl_pers_string);
|
---|
374 | }
|
---|
375 | if (perslen > drbg->max_perslen) {
|
---|
376 | ERR_raise(ERR_LIB_PROV, PROV_R_PERSONALISATION_STRING_TOO_LONG);
|
---|
377 | goto end;
|
---|
378 | }
|
---|
379 |
|
---|
380 | if (drbg->state != EVP_RAND_STATE_UNINITIALISED) {
|
---|
381 | if (drbg->state == EVP_RAND_STATE_ERROR)
|
---|
382 | ERR_raise(ERR_LIB_PROV, PROV_R_IN_ERROR_STATE);
|
---|
383 | else
|
---|
384 | ERR_raise(ERR_LIB_PROV, PROV_R_ALREADY_INSTANTIATED);
|
---|
385 | goto end;
|
---|
386 | }
|
---|
387 |
|
---|
388 | drbg->state = EVP_RAND_STATE_ERROR;
|
---|
389 |
|
---|
390 | if (drbg->min_noncelen > 0) {
|
---|
391 | if (drbg->parent_nonce != NULL) {
|
---|
392 | noncelen = drbg->parent_nonce(drbg->parent, NULL, drbg->strength,
|
---|
393 | drbg->min_noncelen,
|
---|
394 | drbg->max_noncelen);
|
---|
395 | if (noncelen == 0) {
|
---|
396 | ERR_raise(ERR_LIB_PROV, PROV_R_ERROR_RETRIEVING_NONCE);
|
---|
397 | goto end;
|
---|
398 | }
|
---|
399 | nonce = OPENSSL_malloc(noncelen);
|
---|
400 | if (nonce == NULL) {
|
---|
401 | ERR_raise(ERR_LIB_PROV, PROV_R_ERROR_RETRIEVING_NONCE);
|
---|
402 | goto end;
|
---|
403 | }
|
---|
404 | if (noncelen != drbg->parent_nonce(drbg->parent, nonce,
|
---|
405 | drbg->strength,
|
---|
406 | drbg->min_noncelen,
|
---|
407 | drbg->max_noncelen)) {
|
---|
408 | ERR_raise(ERR_LIB_PROV, PROV_R_ERROR_RETRIEVING_NONCE);
|
---|
409 | goto end;
|
---|
410 | }
|
---|
411 | #ifndef PROV_RAND_GET_RANDOM_NONCE
|
---|
412 | } else if (drbg->parent != NULL) {
|
---|
413 | #endif
|
---|
414 | /*
|
---|
415 | * NIST SP800-90Ar1 section 9.1 says you can combine getting
|
---|
416 | * the entropy and nonce in 1 call by increasing the entropy
|
---|
417 | * with 50% and increasing the minimum length to accommodate
|
---|
418 | * the length of the nonce. We do this in case a nonce is
|
---|
419 | * required and there is no parental nonce capability.
|
---|
420 | */
|
---|
421 | min_entropy += drbg->strength / 2;
|
---|
422 | min_entropylen += drbg->min_noncelen;
|
---|
423 | max_entropylen += drbg->max_noncelen;
|
---|
424 | }
|
---|
425 | #ifndef PROV_RAND_GET_RANDOM_NONCE
|
---|
426 | else { /* parent == NULL */
|
---|
427 | noncelen = prov_drbg_get_nonce(drbg, &nonce, drbg->min_noncelen,
|
---|
428 | drbg->max_noncelen);
|
---|
429 | if (noncelen < drbg->min_noncelen
|
---|
430 | || noncelen > drbg->max_noncelen) {
|
---|
431 | ERR_raise(ERR_LIB_PROV, PROV_R_ERROR_RETRIEVING_NONCE);
|
---|
432 | goto end;
|
---|
433 | }
|
---|
434 | }
|
---|
435 | #endif
|
---|
436 | }
|
---|
437 |
|
---|
438 | drbg->reseed_next_counter = tsan_load(&drbg->reseed_counter);
|
---|
439 | if (drbg->reseed_next_counter) {
|
---|
440 | drbg->reseed_next_counter++;
|
---|
441 | if (!drbg->reseed_next_counter)
|
---|
442 | drbg->reseed_next_counter = 1;
|
---|
443 | }
|
---|
444 |
|
---|
445 | entropylen = get_entropy(drbg, &entropy, min_entropy,
|
---|
446 | min_entropylen, max_entropylen,
|
---|
447 | prediction_resistance);
|
---|
448 | if (entropylen < min_entropylen
|
---|
449 | || entropylen > max_entropylen) {
|
---|
450 | ERR_raise(ERR_LIB_PROV, PROV_R_ERROR_RETRIEVING_ENTROPY);
|
---|
451 | goto end;
|
---|
452 | }
|
---|
453 |
|
---|
454 | if (!drbg->instantiate(drbg, entropy, entropylen, nonce, noncelen,
|
---|
455 | pers, perslen)) {
|
---|
456 | cleanup_entropy(drbg, entropy, entropylen);
|
---|
457 | ERR_raise(ERR_LIB_PROV, PROV_R_ERROR_INSTANTIATING_DRBG);
|
---|
458 | goto end;
|
---|
459 | }
|
---|
460 | cleanup_entropy(drbg, entropy, entropylen);
|
---|
461 |
|
---|
462 | drbg->state = EVP_RAND_STATE_READY;
|
---|
463 | drbg->generate_counter = 1;
|
---|
464 | drbg->reseed_time = time(NULL);
|
---|
465 | tsan_store(&drbg->reseed_counter, drbg->reseed_next_counter);
|
---|
466 |
|
---|
467 | end:
|
---|
468 | if (nonce != NULL)
|
---|
469 | ossl_prov_cleanup_nonce(drbg->provctx, nonce, noncelen);
|
---|
470 | if (drbg->state == EVP_RAND_STATE_READY)
|
---|
471 | return 1;
|
---|
472 | return 0;
|
---|
473 | }
|
---|
474 |
|
---|
475 | /*
|
---|
476 | * Uninstantiate |drbg|. Must be instantiated before it can be used.
|
---|
477 | *
|
---|
478 | * Requires that drbg->lock is already locked for write, if non-null.
|
---|
479 | *
|
---|
480 | * Returns 1 on success, 0 on failure.
|
---|
481 | */
|
---|
482 | int ossl_prov_drbg_uninstantiate(PROV_DRBG *drbg)
|
---|
483 | {
|
---|
484 | drbg->state = EVP_RAND_STATE_UNINITIALISED;
|
---|
485 | return 1;
|
---|
486 | }
|
---|
487 |
|
---|
488 | /*
|
---|
489 | * Reseed |drbg|, mixing in the specified data
|
---|
490 | *
|
---|
491 | * Requires that drbg->lock is already locked for write, if non-null.
|
---|
492 | *
|
---|
493 | * Returns 1 on success, 0 on failure.
|
---|
494 | */
|
---|
495 | int ossl_prov_drbg_reseed(PROV_DRBG *drbg, int prediction_resistance,
|
---|
496 | const unsigned char *ent, size_t ent_len,
|
---|
497 | const unsigned char *adin, size_t adinlen)
|
---|
498 | {
|
---|
499 | unsigned char *entropy = NULL;
|
---|
500 | size_t entropylen = 0;
|
---|
501 |
|
---|
502 | if (!ossl_prov_is_running())
|
---|
503 | return 0;
|
---|
504 |
|
---|
505 | if (drbg->state != EVP_RAND_STATE_READY) {
|
---|
506 | /* try to recover from previous errors */
|
---|
507 | rand_drbg_restart(drbg);
|
---|
508 |
|
---|
509 | if (drbg->state == EVP_RAND_STATE_ERROR) {
|
---|
510 | ERR_raise(ERR_LIB_PROV, PROV_R_IN_ERROR_STATE);
|
---|
511 | return 0;
|
---|
512 | }
|
---|
513 | if (drbg->state == EVP_RAND_STATE_UNINITIALISED) {
|
---|
514 | ERR_raise(ERR_LIB_PROV, PROV_R_NOT_INSTANTIATED);
|
---|
515 | return 0;
|
---|
516 | }
|
---|
517 | }
|
---|
518 |
|
---|
519 | if (ent != NULL) {
|
---|
520 | if (ent_len < drbg->min_entropylen) {
|
---|
521 | ERR_raise(ERR_LIB_RAND, RAND_R_ENTROPY_OUT_OF_RANGE);
|
---|
522 | drbg->state = EVP_RAND_STATE_ERROR;
|
---|
523 | return 0;
|
---|
524 | }
|
---|
525 | if (ent_len > drbg->max_entropylen) {
|
---|
526 | ERR_raise(ERR_LIB_RAND, RAND_R_ENTROPY_INPUT_TOO_LONG);
|
---|
527 | drbg->state = EVP_RAND_STATE_ERROR;
|
---|
528 | return 0;
|
---|
529 | }
|
---|
530 | }
|
---|
531 |
|
---|
532 | if (adin == NULL) {
|
---|
533 | adinlen = 0;
|
---|
534 | } else if (adinlen > drbg->max_adinlen) {
|
---|
535 | ERR_raise(ERR_LIB_PROV, PROV_R_ADDITIONAL_INPUT_TOO_LONG);
|
---|
536 | return 0;
|
---|
537 | }
|
---|
538 |
|
---|
539 | drbg->state = EVP_RAND_STATE_ERROR;
|
---|
540 |
|
---|
541 | drbg->reseed_next_counter = tsan_load(&drbg->reseed_counter);
|
---|
542 | if (drbg->reseed_next_counter) {
|
---|
543 | drbg->reseed_next_counter++;
|
---|
544 | if (!drbg->reseed_next_counter)
|
---|
545 | drbg->reseed_next_counter = 1;
|
---|
546 | }
|
---|
547 |
|
---|
548 | if (ent != NULL) {
|
---|
549 | #ifdef FIPS_MODULE
|
---|
550 | /*
|
---|
551 | * NIST SP-800-90A mandates that entropy *shall not* be provided
|
---|
552 | * by the consuming application. Instead the data is added as additional
|
---|
553 | * input.
|
---|
554 | *
|
---|
555 | * (NIST SP-800-90Ar1, Sections 9.1 and 9.2)
|
---|
556 | */
|
---|
557 | if (!drbg->reseed(drbg, NULL, 0, ent, ent_len)) {
|
---|
558 | ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_RESEED);
|
---|
559 | return 0;
|
---|
560 | }
|
---|
561 | #else
|
---|
562 | if (!drbg->reseed(drbg, ent, ent_len, adin, adinlen)) {
|
---|
563 | ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_RESEED);
|
---|
564 | return 0;
|
---|
565 | }
|
---|
566 | /* There isn't much point adding the same additional input twice */
|
---|
567 | adin = NULL;
|
---|
568 | adinlen = 0;
|
---|
569 | #endif
|
---|
570 | }
|
---|
571 |
|
---|
572 | /* Reseed using our sources in addition */
|
---|
573 | entropylen = get_entropy(drbg, &entropy, drbg->strength,
|
---|
574 | drbg->min_entropylen, drbg->max_entropylen,
|
---|
575 | prediction_resistance);
|
---|
576 | if (entropylen < drbg->min_entropylen
|
---|
577 | || entropylen > drbg->max_entropylen) {
|
---|
578 | ERR_raise(ERR_LIB_PROV, PROV_R_ERROR_RETRIEVING_ENTROPY);
|
---|
579 | goto end;
|
---|
580 | }
|
---|
581 |
|
---|
582 | if (!drbg->reseed(drbg, entropy, entropylen, adin, adinlen))
|
---|
583 | goto end;
|
---|
584 |
|
---|
585 | drbg->state = EVP_RAND_STATE_READY;
|
---|
586 | drbg->generate_counter = 1;
|
---|
587 | drbg->reseed_time = time(NULL);
|
---|
588 | tsan_store(&drbg->reseed_counter, drbg->reseed_next_counter);
|
---|
589 | if (drbg->parent != NULL)
|
---|
590 | drbg->parent_reseed_counter = get_parent_reseed_count(drbg);
|
---|
591 |
|
---|
592 | end:
|
---|
593 | cleanup_entropy(drbg, entropy, entropylen);
|
---|
594 | if (drbg->state == EVP_RAND_STATE_READY)
|
---|
595 | return 1;
|
---|
596 | return 0;
|
---|
597 | }
|
---|
598 |
|
---|
599 | /*
|
---|
600 | * Generate |outlen| bytes into the buffer at |out|. Reseed if we need
|
---|
601 | * to or if |prediction_resistance| is set. Additional input can be
|
---|
602 | * sent in |adin| and |adinlen|.
|
---|
603 | *
|
---|
604 | * Requires that drbg->lock is already locked for write, if non-null.
|
---|
605 | *
|
---|
606 | * Returns 1 on success, 0 on failure.
|
---|
607 | *
|
---|
608 | */
|
---|
609 | int ossl_prov_drbg_generate(PROV_DRBG *drbg, unsigned char *out, size_t outlen,
|
---|
610 | unsigned int strength, int prediction_resistance,
|
---|
611 | const unsigned char *adin, size_t adinlen)
|
---|
612 | {
|
---|
613 | int fork_id;
|
---|
614 | int reseed_required = 0;
|
---|
615 |
|
---|
616 | if (!ossl_prov_is_running())
|
---|
617 | return 0;
|
---|
618 |
|
---|
619 | if (drbg->state != EVP_RAND_STATE_READY) {
|
---|
620 | /* try to recover from previous errors */
|
---|
621 | rand_drbg_restart(drbg);
|
---|
622 |
|
---|
623 | if (drbg->state == EVP_RAND_STATE_ERROR) {
|
---|
624 | ERR_raise(ERR_LIB_PROV, PROV_R_IN_ERROR_STATE);
|
---|
625 | return 0;
|
---|
626 | }
|
---|
627 | if (drbg->state == EVP_RAND_STATE_UNINITIALISED) {
|
---|
628 | ERR_raise(ERR_LIB_PROV, PROV_R_NOT_INSTANTIATED);
|
---|
629 | return 0;
|
---|
630 | }
|
---|
631 | }
|
---|
632 | if (strength > drbg->strength) {
|
---|
633 | ERR_raise(ERR_LIB_PROV, PROV_R_INSUFFICIENT_DRBG_STRENGTH);
|
---|
634 | return 0;
|
---|
635 | }
|
---|
636 |
|
---|
637 | if (outlen > drbg->max_request) {
|
---|
638 | ERR_raise(ERR_LIB_PROV, PROV_R_REQUEST_TOO_LARGE_FOR_DRBG);
|
---|
639 | return 0;
|
---|
640 | }
|
---|
641 | if (adinlen > drbg->max_adinlen) {
|
---|
642 | ERR_raise(ERR_LIB_PROV, PROV_R_ADDITIONAL_INPUT_TOO_LONG);
|
---|
643 | return 0;
|
---|
644 | }
|
---|
645 |
|
---|
646 | fork_id = openssl_get_fork_id();
|
---|
647 |
|
---|
648 | if (drbg->fork_id != fork_id) {
|
---|
649 | drbg->fork_id = fork_id;
|
---|
650 | reseed_required = 1;
|
---|
651 | }
|
---|
652 |
|
---|
653 | if (drbg->reseed_interval > 0) {
|
---|
654 | if (drbg->generate_counter >= drbg->reseed_interval)
|
---|
655 | reseed_required = 1;
|
---|
656 | }
|
---|
657 | if (drbg->reseed_time_interval > 0) {
|
---|
658 | time_t now = time(NULL);
|
---|
659 | if (now < drbg->reseed_time
|
---|
660 | || now - drbg->reseed_time >= drbg->reseed_time_interval)
|
---|
661 | reseed_required = 1;
|
---|
662 | }
|
---|
663 | if (drbg->parent != NULL
|
---|
664 | && get_parent_reseed_count(drbg) != drbg->parent_reseed_counter)
|
---|
665 | reseed_required = 1;
|
---|
666 |
|
---|
667 | if (reseed_required || prediction_resistance) {
|
---|
668 | if (!ossl_prov_drbg_reseed(drbg, prediction_resistance, NULL, 0,
|
---|
669 | adin, adinlen)) {
|
---|
670 | ERR_raise(ERR_LIB_PROV, PROV_R_RESEED_ERROR);
|
---|
671 | return 0;
|
---|
672 | }
|
---|
673 | adin = NULL;
|
---|
674 | adinlen = 0;
|
---|
675 | }
|
---|
676 |
|
---|
677 | if (!drbg->generate(drbg, out, outlen, adin, adinlen)) {
|
---|
678 | drbg->state = EVP_RAND_STATE_ERROR;
|
---|
679 | ERR_raise(ERR_LIB_PROV, PROV_R_GENERATE_ERROR);
|
---|
680 | return 0;
|
---|
681 | }
|
---|
682 |
|
---|
683 | drbg->generate_counter++;
|
---|
684 |
|
---|
685 | return 1;
|
---|
686 | }
|
---|
687 |
|
---|
688 | /*
|
---|
689 | * Restart |drbg|, using the specified entropy or additional input
|
---|
690 | *
|
---|
691 | * Tries its best to get the drbg instantiated by all means,
|
---|
692 | * regardless of its current state.
|
---|
693 | *
|
---|
694 | * Optionally, a |buffer| of |len| random bytes can be passed,
|
---|
695 | * which is assumed to contain at least |entropy| bits of entropy.
|
---|
696 | *
|
---|
697 | * If |entropy| > 0, the buffer content is used as entropy input.
|
---|
698 | *
|
---|
699 | * If |entropy| == 0, the buffer content is used as additional input
|
---|
700 | *
|
---|
701 | * Returns 1 on success, 0 on failure.
|
---|
702 | *
|
---|
703 | * This function is used internally only.
|
---|
704 | */
|
---|
705 | static int rand_drbg_restart(PROV_DRBG *drbg)
|
---|
706 | {
|
---|
707 | /* repair error state */
|
---|
708 | if (drbg->state == EVP_RAND_STATE_ERROR)
|
---|
709 | drbg->uninstantiate(drbg);
|
---|
710 |
|
---|
711 | /* repair uninitialized state */
|
---|
712 | if (drbg->state == EVP_RAND_STATE_UNINITIALISED)
|
---|
713 | /* reinstantiate drbg */
|
---|
714 | ossl_prov_drbg_instantiate(drbg, drbg->strength, 0, NULL, 0);
|
---|
715 |
|
---|
716 | return drbg->state == EVP_RAND_STATE_READY;
|
---|
717 | }
|
---|
718 |
|
---|
719 | /* Provider support from here down */
|
---|
720 | static const OSSL_DISPATCH *find_call(const OSSL_DISPATCH *dispatch,
|
---|
721 | int function)
|
---|
722 | {
|
---|
723 | if (dispatch != NULL)
|
---|
724 | while (dispatch->function_id != 0) {
|
---|
725 | if (dispatch->function_id == function)
|
---|
726 | return dispatch;
|
---|
727 | dispatch++;
|
---|
728 | }
|
---|
729 | return NULL;
|
---|
730 | }
|
---|
731 |
|
---|
732 | int ossl_drbg_enable_locking(void *vctx)
|
---|
733 | {
|
---|
734 | PROV_DRBG *drbg = vctx;
|
---|
735 |
|
---|
736 | if (drbg != NULL && drbg->lock == NULL) {
|
---|
737 | if (drbg->parent_enable_locking != NULL)
|
---|
738 | if (!drbg->parent_enable_locking(drbg->parent)) {
|
---|
739 | ERR_raise(ERR_LIB_PROV, PROV_R_PARENT_LOCKING_NOT_ENABLED);
|
---|
740 | return 0;
|
---|
741 | }
|
---|
742 | drbg->lock = CRYPTO_THREAD_lock_new();
|
---|
743 | if (drbg->lock == NULL) {
|
---|
744 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_CREATE_LOCK);
|
---|
745 | return 0;
|
---|
746 | }
|
---|
747 | }
|
---|
748 | return 1;
|
---|
749 | }
|
---|
750 |
|
---|
751 | /*
|
---|
752 | * Allocate memory and initialize a new DRBG. The DRBG is allocated on
|
---|
753 | * the secure heap if |secure| is nonzero and the secure heap is enabled.
|
---|
754 | * The |parent|, if not NULL, will be used as random source for reseeding.
|
---|
755 | * This also requires the parent's provider context and the parent's lock.
|
---|
756 | *
|
---|
757 | * Returns a pointer to the new DRBG instance on success, NULL on failure.
|
---|
758 | */
|
---|
759 | PROV_DRBG *ossl_rand_drbg_new
|
---|
760 | (void *provctx, void *parent, const OSSL_DISPATCH *p_dispatch,
|
---|
761 | int (*dnew)(PROV_DRBG *ctx),
|
---|
762 | int (*instantiate)(PROV_DRBG *drbg,
|
---|
763 | const unsigned char *entropy, size_t entropylen,
|
---|
764 | const unsigned char *nonce, size_t noncelen,
|
---|
765 | const unsigned char *pers, size_t perslen),
|
---|
766 | int (*uninstantiate)(PROV_DRBG *ctx),
|
---|
767 | int (*reseed)(PROV_DRBG *drbg, const unsigned char *ent, size_t ent_len,
|
---|
768 | const unsigned char *adin, size_t adin_len),
|
---|
769 | int (*generate)(PROV_DRBG *, unsigned char *out, size_t outlen,
|
---|
770 | const unsigned char *adin, size_t adin_len))
|
---|
771 | {
|
---|
772 | PROV_DRBG *drbg;
|
---|
773 | unsigned int p_str;
|
---|
774 | const OSSL_DISPATCH *pfunc;
|
---|
775 |
|
---|
776 | if (!ossl_prov_is_running())
|
---|
777 | return NULL;
|
---|
778 |
|
---|
779 | drbg = OPENSSL_zalloc(sizeof(*drbg));
|
---|
780 | if (drbg == NULL) {
|
---|
781 | ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
|
---|
782 | return NULL;
|
---|
783 | }
|
---|
784 |
|
---|
785 | drbg->provctx = provctx;
|
---|
786 | drbg->instantiate = instantiate;
|
---|
787 | drbg->uninstantiate = uninstantiate;
|
---|
788 | drbg->reseed = reseed;
|
---|
789 | drbg->generate = generate;
|
---|
790 | drbg->fork_id = openssl_get_fork_id();
|
---|
791 |
|
---|
792 | /* Extract parent's functions */
|
---|
793 | drbg->parent = parent;
|
---|
794 | if ((pfunc = find_call(p_dispatch, OSSL_FUNC_RAND_ENABLE_LOCKING)) != NULL)
|
---|
795 | drbg->parent_enable_locking = OSSL_FUNC_rand_enable_locking(pfunc);
|
---|
796 | if ((pfunc = find_call(p_dispatch, OSSL_FUNC_RAND_LOCK)) != NULL)
|
---|
797 | drbg->parent_lock = OSSL_FUNC_rand_lock(pfunc);
|
---|
798 | if ((pfunc = find_call(p_dispatch, OSSL_FUNC_RAND_UNLOCK)) != NULL)
|
---|
799 | drbg->parent_unlock = OSSL_FUNC_rand_unlock(pfunc);
|
---|
800 | if ((pfunc = find_call(p_dispatch, OSSL_FUNC_RAND_GET_CTX_PARAMS)) != NULL)
|
---|
801 | drbg->parent_get_ctx_params = OSSL_FUNC_rand_get_ctx_params(pfunc);
|
---|
802 | if ((pfunc = find_call(p_dispatch, OSSL_FUNC_RAND_NONCE)) != NULL)
|
---|
803 | drbg->parent_nonce = OSSL_FUNC_rand_nonce(pfunc);
|
---|
804 | if ((pfunc = find_call(p_dispatch, OSSL_FUNC_RAND_GET_SEED)) != NULL)
|
---|
805 | drbg->parent_get_seed = OSSL_FUNC_rand_get_seed(pfunc);
|
---|
806 | if ((pfunc = find_call(p_dispatch, OSSL_FUNC_RAND_CLEAR_SEED)) != NULL)
|
---|
807 | drbg->parent_clear_seed = OSSL_FUNC_rand_clear_seed(pfunc);
|
---|
808 |
|
---|
809 | /* Set some default maximums up */
|
---|
810 | drbg->max_entropylen = DRBG_MAX_LENGTH;
|
---|
811 | drbg->max_noncelen = DRBG_MAX_LENGTH;
|
---|
812 | drbg->max_perslen = DRBG_MAX_LENGTH;
|
---|
813 | drbg->max_adinlen = DRBG_MAX_LENGTH;
|
---|
814 | drbg->generate_counter = 1;
|
---|
815 | drbg->reseed_counter = 1;
|
---|
816 | drbg->reseed_interval = RESEED_INTERVAL;
|
---|
817 | drbg->reseed_time_interval = TIME_INTERVAL;
|
---|
818 |
|
---|
819 | if (!dnew(drbg))
|
---|
820 | goto err;
|
---|
821 |
|
---|
822 | if (parent != NULL) {
|
---|
823 | if (!get_parent_strength(drbg, &p_str))
|
---|
824 | goto err;
|
---|
825 | if (drbg->strength > p_str) {
|
---|
826 | /*
|
---|
827 | * We currently don't support the algorithm from NIST SP 800-90C
|
---|
828 | * 10.1.2 to use a weaker DRBG as source
|
---|
829 | */
|
---|
830 | ERR_raise(ERR_LIB_PROV, PROV_R_PARENT_STRENGTH_TOO_WEAK);
|
---|
831 | goto err;
|
---|
832 | }
|
---|
833 | }
|
---|
834 | #ifdef TSAN_REQUIRES_LOCKING
|
---|
835 | if (!ossl_drbg_enable_locking(drbg))
|
---|
836 | goto err;
|
---|
837 | #endif
|
---|
838 | return drbg;
|
---|
839 |
|
---|
840 | err:
|
---|
841 | ossl_rand_drbg_free(drbg);
|
---|
842 | return NULL;
|
---|
843 | }
|
---|
844 |
|
---|
845 | void ossl_rand_drbg_free(PROV_DRBG *drbg)
|
---|
846 | {
|
---|
847 | if (drbg == NULL)
|
---|
848 | return;
|
---|
849 |
|
---|
850 | CRYPTO_THREAD_lock_free(drbg->lock);
|
---|
851 | OPENSSL_free(drbg);
|
---|
852 | }
|
---|
853 |
|
---|
854 | int ossl_drbg_get_ctx_params(PROV_DRBG *drbg, OSSL_PARAM params[])
|
---|
855 | {
|
---|
856 | OSSL_PARAM *p;
|
---|
857 |
|
---|
858 | p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STATE);
|
---|
859 | if (p != NULL && !OSSL_PARAM_set_int(p, drbg->state))
|
---|
860 | return 0;
|
---|
861 |
|
---|
862 | p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STRENGTH);
|
---|
863 | if (p != NULL && !OSSL_PARAM_set_int(p, drbg->strength))
|
---|
864 | return 0;
|
---|
865 |
|
---|
866 | p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST);
|
---|
867 | if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->max_request))
|
---|
868 | return 0;
|
---|
869 |
|
---|
870 | p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_MIN_ENTROPYLEN);
|
---|
871 | if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->min_entropylen))
|
---|
872 | return 0;
|
---|
873 |
|
---|
874 | p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_MAX_ENTROPYLEN);
|
---|
875 | if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->max_entropylen))
|
---|
876 | return 0;
|
---|
877 |
|
---|
878 | p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_MIN_NONCELEN);
|
---|
879 | if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->min_noncelen))
|
---|
880 | return 0;
|
---|
881 |
|
---|
882 | p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_MAX_NONCELEN);
|
---|
883 | if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->max_noncelen))
|
---|
884 | return 0;
|
---|
885 |
|
---|
886 | p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_MAX_PERSLEN);
|
---|
887 | if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->max_perslen))
|
---|
888 | return 0;
|
---|
889 |
|
---|
890 | p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_MAX_ADINLEN);
|
---|
891 | if (p != NULL && !OSSL_PARAM_set_size_t(p, drbg->max_adinlen))
|
---|
892 | return 0;
|
---|
893 |
|
---|
894 | p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_RESEED_REQUESTS);
|
---|
895 | if (p != NULL && !OSSL_PARAM_set_uint(p, drbg->reseed_interval))
|
---|
896 | return 0;
|
---|
897 |
|
---|
898 | p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_RESEED_TIME);
|
---|
899 | if (p != NULL && !OSSL_PARAM_set_time_t(p, drbg->reseed_time))
|
---|
900 | return 0;
|
---|
901 |
|
---|
902 | p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL);
|
---|
903 | if (p != NULL && !OSSL_PARAM_set_time_t(p, drbg->reseed_time_interval))
|
---|
904 | return 0;
|
---|
905 |
|
---|
906 | p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_RESEED_COUNTER);
|
---|
907 | if (p != NULL
|
---|
908 | && !OSSL_PARAM_set_uint(p, tsan_load(&drbg->reseed_counter)))
|
---|
909 | return 0;
|
---|
910 | return 1;
|
---|
911 | }
|
---|
912 |
|
---|
913 | int ossl_drbg_set_ctx_params(PROV_DRBG *drbg, const OSSL_PARAM params[])
|
---|
914 | {
|
---|
915 | const OSSL_PARAM *p;
|
---|
916 |
|
---|
917 | if (params == NULL)
|
---|
918 | return 1;
|
---|
919 |
|
---|
920 | p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_RESEED_REQUESTS);
|
---|
921 | if (p != NULL && !OSSL_PARAM_get_uint(p, &drbg->reseed_interval))
|
---|
922 | return 0;
|
---|
923 |
|
---|
924 | p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL);
|
---|
925 | if (p != NULL && !OSSL_PARAM_get_time_t(p, &drbg->reseed_time_interval))
|
---|
926 | return 0;
|
---|
927 | return 1;
|
---|
928 | }
|
---|