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