]> git.ipfire.org Git - thirdparty/openssl.git/blob - providers/implementations/rands/drbg_ctr.c
rand: remove unimplemented librandom stub code
[thirdparty/openssl.git] / providers / implementations / rands / drbg_ctr.c
1 /*
2 * Copyright 2011-2024 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 <stdlib.h>
11 #include <string.h>
12 #include <openssl/crypto.h>
13 #include <openssl/err.h>
14 #include <openssl/rand.h>
15 #include <openssl/aes.h>
16 #include <openssl/proverr.h>
17 #include "crypto/modes.h"
18 #include "internal/thread_once.h"
19 #include "prov/implementations.h"
20 #include "prov/providercommon.h"
21 #include "prov/provider_ctx.h"
22 #include "drbg_local.h"
23
24 static OSSL_FUNC_rand_newctx_fn drbg_ctr_new_wrapper;
25 static OSSL_FUNC_rand_freectx_fn drbg_ctr_free;
26 static OSSL_FUNC_rand_instantiate_fn drbg_ctr_instantiate_wrapper;
27 static OSSL_FUNC_rand_uninstantiate_fn drbg_ctr_uninstantiate_wrapper;
28 static OSSL_FUNC_rand_generate_fn drbg_ctr_generate_wrapper;
29 static OSSL_FUNC_rand_reseed_fn drbg_ctr_reseed_wrapper;
30 static OSSL_FUNC_rand_settable_ctx_params_fn drbg_ctr_settable_ctx_params;
31 static OSSL_FUNC_rand_set_ctx_params_fn drbg_ctr_set_ctx_params;
32 static OSSL_FUNC_rand_gettable_ctx_params_fn drbg_ctr_gettable_ctx_params;
33 static OSSL_FUNC_rand_get_ctx_params_fn drbg_ctr_get_ctx_params;
34 static OSSL_FUNC_rand_verify_zeroization_fn drbg_ctr_verify_zeroization;
35
36 static int drbg_ctr_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[]);
37
38 /*
39 * The state of a DRBG AES-CTR.
40 */
41 typedef struct rand_drbg_ctr_st {
42 EVP_CIPHER_CTX *ctx_ecb;
43 EVP_CIPHER_CTX *ctx_ctr;
44 EVP_CIPHER_CTX *ctx_df;
45 EVP_CIPHER *cipher_ecb;
46 EVP_CIPHER *cipher_ctr;
47 size_t keylen;
48 int use_df;
49 unsigned char K[32];
50 unsigned char V[16];
51 /* Temporary block storage used by ctr_df */
52 unsigned char bltmp[16];
53 size_t bltmp_pos;
54 unsigned char KX[48];
55 } PROV_DRBG_CTR;
56
57 /*
58 * Implementation of NIST SP 800-90A CTR DRBG.
59 */
60 static void inc_128(PROV_DRBG_CTR *ctr)
61 {
62 unsigned char *p = &ctr->V[0];
63 u32 n = 16, c = 1;
64
65 do {
66 --n;
67 c += p[n];
68 p[n] = (u8)c;
69 c >>= 8;
70 } while (n);
71 }
72
73 static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
74 {
75 size_t i, n;
76
77 if (in == NULL || inlen == 0)
78 return;
79
80 /*
81 * Any zero padding will have no effect on the result as we
82 * are XORing. So just process however much input we have.
83 */
84 n = inlen < ctr->keylen ? inlen : ctr->keylen;
85 for (i = 0; i < n; i++)
86 ctr->K[i] ^= in[i];
87 if (inlen <= ctr->keylen)
88 return;
89
90 n = inlen - ctr->keylen;
91 if (n > 16) {
92 /* Should never happen */
93 n = 16;
94 }
95 for (i = 0; i < n; i++)
96 ctr->V[i] ^= in[i + ctr->keylen];
97 }
98
99 /*
100 * Process a complete block using BCC algorithm of SP 800-90A 10.3.3
101 */
102 __owur static int ctr_BCC_block(PROV_DRBG_CTR *ctr, unsigned char *out,
103 const unsigned char *in, int len)
104 {
105 int i, outlen = AES_BLOCK_SIZE;
106
107 for (i = 0; i < len; i++)
108 out[i] ^= in[i];
109
110 if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
111 || outlen != len)
112 return 0;
113 return 1;
114 }
115
116
117 /*
118 * Handle several BCC operations for as much data as we need for K and X
119 */
120 __owur static int ctr_BCC_blocks(PROV_DRBG_CTR *ctr, const unsigned char *in)
121 {
122 unsigned char in_tmp[48];
123 unsigned char num_of_blk = 2;
124
125 memcpy(in_tmp, in, 16);
126 memcpy(in_tmp + 16, in, 16);
127 if (ctr->keylen != 16) {
128 memcpy(in_tmp + 32, in, 16);
129 num_of_blk = 3;
130 }
131 return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
132 }
133
134 /*
135 * Initialise BCC blocks: these have the value 0,1,2 in leftmost positions:
136 * see 10.3.1 stage 7.
137 */
138 __owur static int ctr_BCC_init(PROV_DRBG_CTR *ctr)
139 {
140 unsigned char bltmp[48] = {0};
141 unsigned char num_of_blk;
142
143 memset(ctr->KX, 0, 48);
144 num_of_blk = ctr->keylen == 16 ? 2 : 3;
145 bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
146 bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
147 return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
148 }
149
150 /*
151 * Process several blocks into BCC algorithm, some possibly partial
152 */
153 __owur static int ctr_BCC_update(PROV_DRBG_CTR *ctr,
154 const unsigned char *in, size_t inlen)
155 {
156 if (in == NULL || inlen == 0)
157 return 1;
158
159 /* If we have partial block handle it first */
160 if (ctr->bltmp_pos) {
161 size_t left = 16 - ctr->bltmp_pos;
162
163 /* If we now have a complete block process it */
164 if (inlen >= left) {
165 memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
166 if (!ctr_BCC_blocks(ctr, ctr->bltmp))
167 return 0;
168 ctr->bltmp_pos = 0;
169 inlen -= left;
170 in += left;
171 }
172 }
173
174 /* Process zero or more complete blocks */
175 for (; inlen >= 16; in += 16, inlen -= 16) {
176 if (!ctr_BCC_blocks(ctr, in))
177 return 0;
178 }
179
180 /* Copy any remaining partial block to the temporary buffer */
181 if (inlen > 0) {
182 memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
183 ctr->bltmp_pos += inlen;
184 }
185 return 1;
186 }
187
188 __owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr)
189 {
190 if (ctr->bltmp_pos) {
191 memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
192 if (!ctr_BCC_blocks(ctr, ctr->bltmp))
193 return 0;
194 }
195 return 1;
196 }
197
198 __owur static int ctr_df(PROV_DRBG_CTR *ctr,
199 const unsigned char *in1, size_t in1len,
200 const unsigned char *in2, size_t in2len,
201 const unsigned char *in3, size_t in3len)
202 {
203 static unsigned char c80 = 0x80;
204 size_t inlen;
205 unsigned char *p = ctr->bltmp;
206 int outlen = AES_BLOCK_SIZE;
207
208 if (!ctr_BCC_init(ctr))
209 return 0;
210 if (in1 == NULL)
211 in1len = 0;
212 if (in2 == NULL)
213 in2len = 0;
214 if (in3 == NULL)
215 in3len = 0;
216 inlen = in1len + in2len + in3len;
217 /* Initialise L||N in temporary block */
218 *p++ = (inlen >> 24) & 0xff;
219 *p++ = (inlen >> 16) & 0xff;
220 *p++ = (inlen >> 8) & 0xff;
221 *p++ = inlen & 0xff;
222
223 /* NB keylen is at most 32 bytes */
224 *p++ = 0;
225 *p++ = 0;
226 *p++ = 0;
227 *p = (unsigned char)((ctr->keylen + 16) & 0xff);
228 ctr->bltmp_pos = 8;
229 if (!ctr_BCC_update(ctr, in1, in1len)
230 || !ctr_BCC_update(ctr, in2, in2len)
231 || !ctr_BCC_update(ctr, in3, in3len)
232 || !ctr_BCC_update(ctr, &c80, 1)
233 || !ctr_BCC_final(ctr))
234 return 0;
235 /* Set up key K */
236 if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
237 return 0;
238 /* X follows key K */
239 if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
240 AES_BLOCK_SIZE)
241 || outlen != AES_BLOCK_SIZE)
242 return 0;
243 if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
244 AES_BLOCK_SIZE)
245 || outlen != AES_BLOCK_SIZE)
246 return 0;
247 if (ctr->keylen != 16)
248 if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
249 ctr->KX + 16, AES_BLOCK_SIZE)
250 || outlen != AES_BLOCK_SIZE)
251 return 0;
252 return 1;
253 }
254
255 /*
256 * NB the no-df Update in SP800-90A specifies a constant input length
257 * of seedlen, however other uses of this algorithm pad the input with
258 * zeroes if necessary and have up to two parameters XORed together,
259 * so we handle both cases in this function instead.
260 */
261 __owur static int ctr_update(PROV_DRBG *drbg,
262 const unsigned char *in1, size_t in1len,
263 const unsigned char *in2, size_t in2len,
264 const unsigned char *nonce, size_t noncelen)
265 {
266 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
267 int outlen = AES_BLOCK_SIZE;
268 unsigned char V_tmp[48], out[48];
269 unsigned char len;
270
271 /* correct key is already set up. */
272 memcpy(V_tmp, ctr->V, 16);
273 inc_128(ctr);
274 memcpy(V_tmp + 16, ctr->V, 16);
275 if (ctr->keylen == 16) {
276 len = 32;
277 } else {
278 inc_128(ctr);
279 memcpy(V_tmp + 32, ctr->V, 16);
280 len = 48;
281 }
282 if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
283 || outlen != len)
284 return 0;
285 memcpy(ctr->K, out, ctr->keylen);
286 memcpy(ctr->V, out + ctr->keylen, 16);
287
288 if (ctr->use_df) {
289 /* If no input reuse existing derived value */
290 if (in1 != NULL || nonce != NULL || in2 != NULL)
291 if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
292 return 0;
293 /* If this a reuse input in1len != 0 */
294 if (in1len)
295 ctr_XOR(ctr, ctr->KX, drbg->seedlen);
296 } else {
297 ctr_XOR(ctr, in1, in1len);
298 ctr_XOR(ctr, in2, in2len);
299 }
300
301 if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
302 || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
303 return 0;
304 return 1;
305 }
306
307 static int drbg_ctr_instantiate(PROV_DRBG *drbg,
308 const unsigned char *entropy, size_t entropylen,
309 const unsigned char *nonce, size_t noncelen,
310 const unsigned char *pers, size_t perslen)
311 {
312 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
313
314 if (entropy == NULL)
315 return 0;
316
317 memset(ctr->K, 0, sizeof(ctr->K));
318 memset(ctr->V, 0, sizeof(ctr->V));
319 if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
320 return 0;
321
322 inc_128(ctr);
323 if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
324 return 0;
325 return 1;
326 }
327
328 static int drbg_ctr_instantiate_wrapper(void *vdrbg, unsigned int strength,
329 int prediction_resistance,
330 const unsigned char *pstr,
331 size_t pstr_len,
332 const OSSL_PARAM params[])
333 {
334 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
335 int ret = 0;
336
337 if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
338 return 0;
339
340 if (!ossl_prov_is_running()
341 || !drbg_ctr_set_ctx_params_locked(drbg, params))
342 goto err;
343 ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
344 pstr, pstr_len);
345 err:
346 if (drbg->lock != NULL)
347 CRYPTO_THREAD_unlock(drbg->lock);
348 return ret;
349 }
350
351 static int drbg_ctr_reseed(PROV_DRBG *drbg,
352 const unsigned char *entropy, size_t entropylen,
353 const unsigned char *adin, size_t adinlen)
354 {
355 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
356
357 if (entropy == NULL)
358 return 0;
359
360 inc_128(ctr);
361 if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
362 return 0;
363 return 1;
364 }
365
366 static int drbg_ctr_reseed_wrapper(void *vdrbg, int prediction_resistance,
367 const unsigned char *ent, size_t ent_len,
368 const unsigned char *adin, size_t adin_len)
369 {
370 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
371
372 return ossl_prov_drbg_reseed(drbg, prediction_resistance, ent, ent_len,
373 adin, adin_len);
374 }
375
376 static void ctr96_inc(unsigned char *counter)
377 {
378 u32 n = 12, c = 1;
379
380 do {
381 --n;
382 c += counter[n];
383 counter[n] = (u8)c;
384 c >>= 8;
385 } while (n);
386 }
387
388 static int drbg_ctr_generate(PROV_DRBG *drbg,
389 unsigned char *out, size_t outlen,
390 const unsigned char *adin, size_t adinlen)
391 {
392 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
393 unsigned int ctr32, blocks;
394 int outl, buflen;
395
396 if (adin != NULL && adinlen != 0) {
397 inc_128(ctr);
398
399 if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
400 return 0;
401 /* This means we reuse derived value */
402 if (ctr->use_df) {
403 adin = NULL;
404 adinlen = 1;
405 }
406 } else {
407 adinlen = 0;
408 }
409
410 inc_128(ctr);
411
412 if (outlen == 0) {
413 inc_128(ctr);
414
415 if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
416 return 0;
417 return 1;
418 }
419
420 memset(out, 0, outlen);
421
422 do {
423 if (!EVP_CipherInit_ex(ctr->ctx_ctr,
424 NULL, NULL, NULL, ctr->V, -1))
425 return 0;
426
427 /*-
428 * outlen has type size_t while EVP_CipherUpdate takes an
429 * int argument and thus cannot be guaranteed to process more
430 * than 2^31-1 bytes at a time. We process such huge generate
431 * requests in 2^30 byte chunks, which is the greatest multiple
432 * of AES block size lower than or equal to 2^31-1.
433 */
434 buflen = outlen > (1U << 30) ? (1U << 30) : outlen;
435 blocks = (buflen + 15) / 16;
436
437 ctr32 = GETU32(ctr->V + 12) + blocks;
438 if (ctr32 < blocks) {
439 /* 32-bit counter overflow into V. */
440 if (ctr32 != 0) {
441 blocks -= ctr32;
442 buflen = blocks * 16;
443 ctr32 = 0;
444 }
445 ctr96_inc(ctr->V);
446 }
447 PUTU32(ctr->V + 12, ctr32);
448
449 if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
450 || outl != buflen)
451 return 0;
452
453 out += buflen;
454 outlen -= buflen;
455 } while (outlen);
456
457 if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
458 return 0;
459 return 1;
460 }
461
462 static int drbg_ctr_generate_wrapper
463 (void *vdrbg, unsigned char *out, size_t outlen,
464 unsigned int strength, int prediction_resistance,
465 const unsigned char *adin, size_t adin_len)
466 {
467 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
468
469 return ossl_prov_drbg_generate(drbg, out, outlen, strength,
470 prediction_resistance, adin, adin_len);
471 }
472
473 static int drbg_ctr_uninstantiate(PROV_DRBG *drbg)
474 {
475 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
476
477 OPENSSL_cleanse(ctr->K, sizeof(ctr->K));
478 OPENSSL_cleanse(ctr->V, sizeof(ctr->V));
479 OPENSSL_cleanse(ctr->bltmp, sizeof(ctr->bltmp));
480 OPENSSL_cleanse(ctr->KX, sizeof(ctr->KX));
481 ctr->bltmp_pos = 0;
482 return ossl_prov_drbg_uninstantiate(drbg);
483 }
484
485 static int drbg_ctr_uninstantiate_wrapper(void *vdrbg)
486 {
487 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
488 int ret;
489
490 if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
491 return 0;
492
493 ret = drbg_ctr_uninstantiate(drbg);
494
495 if (drbg->lock != NULL)
496 CRYPTO_THREAD_unlock(drbg->lock);
497
498 return ret;
499 }
500
501 static int drbg_ctr_verify_zeroization(void *vdrbg)
502 {
503 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
504 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
505 int ret = 0;
506
507 if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
508 return 0;
509
510 PROV_DRBG_VERIFY_ZEROIZATION(ctr->K);
511 PROV_DRBG_VERIFY_ZEROIZATION(ctr->V);
512 PROV_DRBG_VERIFY_ZEROIZATION(ctr->bltmp);
513 PROV_DRBG_VERIFY_ZEROIZATION(ctr->KX);
514 if (ctr->bltmp_pos != 0)
515 goto err;
516
517 ret = 1;
518 err:
519 if (drbg->lock != NULL)
520 CRYPTO_THREAD_unlock(drbg->lock);
521 return ret;
522 }
523
524 static int drbg_ctr_init_lengths(PROV_DRBG *drbg)
525 {
526 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
527 int res = 1;
528
529 /* Maximum number of bits per request = 2^19 = 2^16 bytes */
530 drbg->max_request = 1 << 16;
531 if (ctr->use_df) {
532 drbg->min_entropylen = 0;
533 drbg->max_entropylen = DRBG_MAX_LENGTH;
534 drbg->min_noncelen = 0;
535 drbg->max_noncelen = DRBG_MAX_LENGTH;
536 drbg->max_perslen = DRBG_MAX_LENGTH;
537 drbg->max_adinlen = DRBG_MAX_LENGTH;
538
539 if (ctr->keylen > 0) {
540 drbg->min_entropylen = ctr->keylen;
541 drbg->min_noncelen = drbg->min_entropylen / 2;
542 }
543 } else {
544 const size_t len = ctr->keylen > 0 ? drbg->seedlen : DRBG_MAX_LENGTH;
545
546 drbg->min_entropylen = len;
547 drbg->max_entropylen = len;
548 /* Nonce not used */
549 drbg->min_noncelen = 0;
550 drbg->max_noncelen = 0;
551 drbg->max_perslen = len;
552 drbg->max_adinlen = len;
553 }
554 return res;
555 }
556
557 static int drbg_ctr_init(PROV_DRBG *drbg)
558 {
559 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
560 size_t keylen;
561
562 if (ctr->cipher_ctr == NULL) {
563 ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
564 return 0;
565 }
566 ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
567 if (ctr->ctx_ecb == NULL)
568 ctr->ctx_ecb = EVP_CIPHER_CTX_new();
569 if (ctr->ctx_ctr == NULL)
570 ctr->ctx_ctr = EVP_CIPHER_CTX_new();
571 if (ctr->ctx_ecb == NULL || ctr->ctx_ctr == NULL) {
572 ERR_raise(ERR_LIB_PROV, ERR_R_EVP_LIB);
573 goto err;
574 }
575
576 if (!EVP_CipherInit_ex(ctr->ctx_ecb,
577 ctr->cipher_ecb, NULL, NULL, NULL, 1)
578 || !EVP_CipherInit_ex(ctr->ctx_ctr,
579 ctr->cipher_ctr, NULL, NULL, NULL, 1)) {
580 ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_INITIALISE_CIPHERS);
581 goto err;
582 }
583
584 drbg->strength = keylen * 8;
585 drbg->seedlen = keylen + 16;
586
587 if (ctr->use_df) {
588 /* df initialisation */
589 static const unsigned char df_key[32] = {
590 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
591 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
592 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
593 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
594 };
595
596 if (ctr->ctx_df == NULL)
597 ctr->ctx_df = EVP_CIPHER_CTX_new();
598 if (ctr->ctx_df == NULL) {
599 ERR_raise(ERR_LIB_PROV, ERR_R_EVP_LIB);
600 goto err;
601 }
602 /* Set key schedule for df_key */
603 if (!EVP_CipherInit_ex(ctr->ctx_df,
604 ctr->cipher_ecb, NULL, df_key, NULL, 1)) {
605 ERR_raise(ERR_LIB_PROV, PROV_R_DERIVATION_FUNCTION_INIT_FAILED);
606 goto err;
607 }
608 }
609 return drbg_ctr_init_lengths(drbg);
610
611 err:
612 EVP_CIPHER_CTX_free(ctr->ctx_ecb);
613 EVP_CIPHER_CTX_free(ctr->ctx_ctr);
614 ctr->ctx_ecb = ctr->ctx_ctr = NULL;
615 return 0;
616 }
617
618 static int drbg_ctr_new(PROV_DRBG *drbg)
619 {
620 PROV_DRBG_CTR *ctr;
621
622 ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
623 if (ctr == NULL)
624 return 0;
625
626 ctr->use_df = 1;
627 drbg->data = ctr;
628 return drbg_ctr_init_lengths(drbg);
629 }
630
631 static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
632 const OSSL_DISPATCH *parent_dispatch)
633 {
634 return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
635 &drbg_ctr_new, &drbg_ctr_free,
636 &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
637 &drbg_ctr_reseed, &drbg_ctr_generate);
638 }
639
640 static void drbg_ctr_free(void *vdrbg)
641 {
642 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
643 PROV_DRBG_CTR *ctr;
644
645 if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
646 EVP_CIPHER_CTX_free(ctr->ctx_ecb);
647 EVP_CIPHER_CTX_free(ctr->ctx_ctr);
648 EVP_CIPHER_CTX_free(ctr->ctx_df);
649 EVP_CIPHER_free(ctr->cipher_ecb);
650 EVP_CIPHER_free(ctr->cipher_ctr);
651
652 OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
653 }
654 ossl_rand_drbg_free(drbg);
655 }
656
657 static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
658 {
659 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
660 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
661 OSSL_PARAM *p;
662 int ret = 0, complete = 0;
663
664 if (!ossl_drbg_get_ctx_params_no_lock(drbg, params, &complete))
665 return 0;
666
667 if (complete)
668 return 1;
669
670 if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
671 return 0;
672
673 p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_USE_DF);
674 if (p != NULL && !OSSL_PARAM_set_int(p, ctr->use_df))
675 goto err;
676
677 p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_CIPHER);
678 if (p != NULL) {
679 if (ctr->cipher_ctr == NULL
680 || !OSSL_PARAM_set_utf8_string(p,
681 EVP_CIPHER_get0_name(ctr->cipher_ctr)))
682 goto err;
683 }
684
685 ret = ossl_drbg_get_ctx_params(drbg, params);
686 err:
687 if (drbg->lock != NULL)
688 CRYPTO_THREAD_unlock(drbg->lock);
689
690 return ret;
691 }
692
693 static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *vctx,
694 ossl_unused void *provctx)
695 {
696 static const OSSL_PARAM known_gettable_ctx_params[] = {
697 OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
698 OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
699 OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON,
700 OSSL_PARAM_END
701 };
702 return known_gettable_ctx_params;
703 }
704
705 static int drbg_ctr_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[])
706 {
707 PROV_DRBG *ctx = (PROV_DRBG *)vctx;
708 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
709 OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
710 const OSSL_PARAM *p;
711 char *ecb;
712 const char *propquery = NULL;
713 int i, cipher_init = 0;
714
715 if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_USE_DF)) != NULL
716 && OSSL_PARAM_get_int(p, &i)) {
717 /* FIPS errors out in the drbg_ctr_init() call later */
718 ctr->use_df = i != 0;
719 cipher_init = 1;
720 }
721
722 if ((p = OSSL_PARAM_locate_const(params,
723 OSSL_DRBG_PARAM_PROPERTIES)) != NULL) {
724 if (p->data_type != OSSL_PARAM_UTF8_STRING)
725 return 0;
726 propquery = (const char *)p->data;
727 }
728
729 if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_CIPHER)) != NULL) {
730 const char *base = (const char *)p->data;
731 size_t ctr_str_len = sizeof("CTR") - 1;
732 size_t ecb_str_len = sizeof("ECB") - 1;
733
734 if (p->data_type != OSSL_PARAM_UTF8_STRING
735 || p->data_size < ctr_str_len)
736 return 0;
737 if (OPENSSL_strcasecmp("CTR", base + p->data_size - ctr_str_len) != 0) {
738 ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
739 return 0;
740 }
741 if ((ecb = OPENSSL_strndup(base, p->data_size)) == NULL)
742 return 0;
743 strcpy(ecb + p->data_size - ecb_str_len, "ECB");
744 EVP_CIPHER_free(ctr->cipher_ecb);
745 EVP_CIPHER_free(ctr->cipher_ctr);
746 ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
747 ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
748 OPENSSL_free(ecb);
749 if (ctr->cipher_ctr == NULL || ctr->cipher_ecb == NULL) {
750 ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_FIND_CIPHERS);
751 return 0;
752 }
753 cipher_init = 1;
754 }
755
756 if (cipher_init && !drbg_ctr_init(ctx))
757 return 0;
758
759 return ossl_drbg_set_ctx_params(ctx, params);
760 }
761
762 static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[])
763 {
764 PROV_DRBG *drbg = (PROV_DRBG *)vctx;
765 int ret;
766
767 if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
768 return 0;
769
770 ret = drbg_ctr_set_ctx_params_locked(vctx, params);
771
772 if (drbg->lock != NULL)
773 CRYPTO_THREAD_unlock(drbg->lock);
774
775 return ret;
776 }
777
778 static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
779 ossl_unused void *provctx)
780 {
781 static const OSSL_PARAM known_settable_ctx_params[] = {
782 OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
783 OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
784 OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
785 OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
786 OSSL_PARAM_END
787 };
788 return known_settable_ctx_params;
789 }
790
791 const OSSL_DISPATCH ossl_drbg_ctr_functions[] = {
792 { OSSL_FUNC_RAND_NEWCTX, (void(*)(void))drbg_ctr_new_wrapper },
793 { OSSL_FUNC_RAND_FREECTX, (void(*)(void))drbg_ctr_free },
794 { OSSL_FUNC_RAND_INSTANTIATE,
795 (void(*)(void))drbg_ctr_instantiate_wrapper },
796 { OSSL_FUNC_RAND_UNINSTANTIATE,
797 (void(*)(void))drbg_ctr_uninstantiate_wrapper },
798 { OSSL_FUNC_RAND_GENERATE, (void(*)(void))drbg_ctr_generate_wrapper },
799 { OSSL_FUNC_RAND_RESEED, (void(*)(void))drbg_ctr_reseed_wrapper },
800 { OSSL_FUNC_RAND_ENABLE_LOCKING, (void(*)(void))ossl_drbg_enable_locking },
801 { OSSL_FUNC_RAND_LOCK, (void(*)(void))ossl_drbg_lock },
802 { OSSL_FUNC_RAND_UNLOCK, (void(*)(void))ossl_drbg_unlock },
803 { OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS,
804 (void(*)(void))drbg_ctr_settable_ctx_params },
805 { OSSL_FUNC_RAND_SET_CTX_PARAMS, (void(*)(void))drbg_ctr_set_ctx_params },
806 { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
807 (void(*)(void))drbg_ctr_gettable_ctx_params },
808 { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))drbg_ctr_get_ctx_params },
809 { OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
810 (void(*)(void))drbg_ctr_verify_zeroization },
811 { OSSL_FUNC_RAND_GET_SEED, (void(*)(void))ossl_drbg_get_seed },
812 { OSSL_FUNC_RAND_CLEAR_SEED, (void(*)(void))ossl_drbg_clear_seed },
813 OSSL_DISPATCH_END
814 };