1 /*
2 * Copyright 2011-2025 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 if (ctr->use_df) {
592 /* df initialisation */
593 static const unsigned char df_key[32] = {
594 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
595 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
596 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
597 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
598 };
599
600 if (ctr->ctx_df == NULL)
601 ctr->ctx_df = EVP_CIPHER_CTX_new();
602 if (ctr->ctx_df == NULL) {
603 ERR_raise(ERR_LIB_PROV, ERR_R_EVP_LIB);
604 goto err;
605 }
606 /* Set key schedule for df_key */
607 if (!EVP_CipherInit_ex(ctr->ctx_df,
608 ctr->cipher_ecb, NULL, df_key, NULL, 1)) {
609 ERR_raise(ERR_LIB_PROV, PROV_R_DERIVATION_FUNCTION_INIT_FAILED);
610 goto err;
611 }
612 }
613 return drbg_ctr_init_lengths(drbg);
614
615 err:
616 EVP_CIPHER_CTX_free(ctr->ctx_ecb);
617 EVP_CIPHER_CTX_free(ctr->ctx_ctr);
618 ctr->ctx_ecb = ctr->ctx_ctr = NULL;
619 return 0;
620 }
621
drbg_ctr_new(PROV_DRBG * drbg)622 static int drbg_ctr_new(PROV_DRBG *drbg)
623 {
624 PROV_DRBG_CTR *ctr;
625
626 ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
627 if (ctr == NULL)
628 return 0;
629
630 ctr->use_df = 1;
631 drbg->data = ctr;
632 OSSL_FIPS_IND_INIT(drbg)
633 return drbg_ctr_init_lengths(drbg);
634 }
635
drbg_ctr_new_wrapper(void * provctx,void * parent,const OSSL_DISPATCH * parent_dispatch)636 static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
637 const OSSL_DISPATCH *parent_dispatch)
638 {
639 return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
640 &drbg_ctr_new, &drbg_ctr_free,
641 &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
642 &drbg_ctr_reseed, &drbg_ctr_generate);
643 }
644
drbg_ctr_free(void * vdrbg)645 static void drbg_ctr_free(void *vdrbg)
646 {
647 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
648 PROV_DRBG_CTR *ctr;
649
650 if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
651 EVP_CIPHER_CTX_free(ctr->ctx_ecb);
652 EVP_CIPHER_CTX_free(ctr->ctx_ctr);
653 EVP_CIPHER_CTX_free(ctr->ctx_df);
654 EVP_CIPHER_free(ctr->cipher_ecb);
655 EVP_CIPHER_free(ctr->cipher_ctr);
656
657 OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
658 }
659 ossl_rand_drbg_free(drbg);
660 }
661
drbg_ctr_get_ctx_params(void * vdrbg,OSSL_PARAM params[])662 static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
663 {
664 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
665 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
666 OSSL_PARAM *p;
667 int ret = 0, complete = 0;
668
669 if (!ossl_drbg_get_ctx_params_no_lock(drbg, params, &complete))
670 return 0;
671
672 if (complete)
673 return 1;
674
675 if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
676 return 0;
677
678 p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_USE_DF);
679 if (p != NULL && !OSSL_PARAM_set_int(p, ctr->use_df))
680 goto err;
681
682 p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_CIPHER);
683 if (p != NULL) {
684 if (ctr->cipher_ctr == NULL
685 || !OSSL_PARAM_set_utf8_string(p,
686 EVP_CIPHER_get0_name(ctr->cipher_ctr)))
687 goto err;
688 }
689
690 ret = ossl_drbg_get_ctx_params(drbg, params);
691 err:
692 if (drbg->lock != NULL)
693 CRYPTO_THREAD_unlock(drbg->lock);
694
695 return ret;
696 }
697
drbg_ctr_gettable_ctx_params(ossl_unused void * vctx,ossl_unused void * provctx)698 static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *vctx,
699 ossl_unused void *provctx)
700 {
701 static const OSSL_PARAM known_gettable_ctx_params[] = {
702 OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
703 OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
704 OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON,
705 OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
706 OSSL_PARAM_END
707 };
708 return known_gettable_ctx_params;
709 }
710
drbg_ctr_set_ctx_params_locked(void * vctx,const OSSL_PARAM params[])711 static int drbg_ctr_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[])
712 {
713 PROV_DRBG *ctx = (PROV_DRBG *)vctx;
714 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
715 OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
716 OSSL_PROVIDER *prov = NULL;
717 const OSSL_PARAM *p;
718 char *ecb;
719 const char *propquery = NULL;
720 int i, cipher_init = 0;
721
722 if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_USE_DF)) != NULL
723 && OSSL_PARAM_get_int(p, &i)) {
724 /* FIPS errors out in the drbg_ctr_init() call later */
725 ctr->use_df = i != 0;
726 cipher_init = 1;
727 }
728
729 if ((p = OSSL_PARAM_locate_const(params,
730 OSSL_DRBG_PARAM_PROPERTIES))
731 != NULL) {
732 if (p->data_type != OSSL_PARAM_UTF8_STRING)
733 return 0;
734 propquery = (const char *)p->data;
735 }
736
737 if ((p = OSSL_PARAM_locate_const(params,
738 OSSL_PROV_PARAM_CORE_PROV_NAME))
739 != NULL) {
740 if (p->data_type != OSSL_PARAM_UTF8_STRING)
741 return 0;
742 if ((prov = ossl_provider_find(libctx,
743 (const char *)p->data, 1))
744 == NULL)
745 return 0;
746 }
747
748 if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_CIPHER)) != NULL) {
749 const char *base = (const char *)p->data;
750 size_t ctr_str_len = sizeof("CTR") - 1;
751 size_t ecb_str_len = sizeof("ECB") - 1;
752
753 if (p->data_type != OSSL_PARAM_UTF8_STRING
754 || p->data_size < ctr_str_len) {
755 ossl_provider_free(prov);
756 return 0;
757 }
758 if (OPENSSL_strcasecmp("CTR", base + p->data_size - ctr_str_len) != 0) {
759 ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
760 ossl_provider_free(prov);
761 return 0;
762 }
763 if ((ecb = OPENSSL_strndup(base, p->data_size)) == NULL) {
764 ossl_provider_free(prov);
765 return 0;
766 }
767 strcpy(ecb + p->data_size - ecb_str_len, "ECB");
768 EVP_CIPHER_free(ctr->cipher_ecb);
769 EVP_CIPHER_free(ctr->cipher_ctr);
770 /*
771 * Try to fetch algorithms from our own provider code, fallback
772 * to generic fetch only if that fails
773 */
774 (void)ERR_set_mark();
775 ctr->cipher_ctr = evp_cipher_fetch_from_prov(prov, base, NULL);
776 if (ctr->cipher_ctr == NULL) {
777 (void)ERR_pop_to_mark();
778 ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
779 } else {
780 (void)ERR_clear_last_mark();
781 }
782 (void)ERR_set_mark();
783 ctr->cipher_ecb = evp_cipher_fetch_from_prov(prov, ecb, NULL);
784 if (ctr->cipher_ecb == NULL) {
785 (void)ERR_pop_to_mark();
786 ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
787 } else {
788 (void)ERR_clear_last_mark();
789 }
790 OPENSSL_free(ecb);
791 if (ctr->cipher_ctr == NULL || ctr->cipher_ecb == NULL) {
792 ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_FIND_CIPHERS);
793 ossl_provider_free(prov);
794 return 0;
795 }
796 cipher_init = 1;
797 }
798 ossl_provider_free(prov);
799
800 if (cipher_init && !drbg_ctr_init(ctx))
801 return 0;
802
803 return ossl_drbg_set_ctx_params(ctx, params);
804 }
805
drbg_ctr_set_ctx_params(void * vctx,const OSSL_PARAM params[])806 static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[])
807 {
808 PROV_DRBG *drbg = (PROV_DRBG *)vctx;
809 int ret;
810
811 if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
812 return 0;
813
814 ret = drbg_ctr_set_ctx_params_locked(vctx, params);
815
816 if (drbg->lock != NULL)
817 CRYPTO_THREAD_unlock(drbg->lock);
818
819 return ret;
820 }
821
drbg_ctr_settable_ctx_params(ossl_unused void * vctx,ossl_unused void * provctx)822 static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
823 ossl_unused void *provctx)
824 {
825 static const OSSL_PARAM known_settable_ctx_params[] = {
826 OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
827 OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
828 OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
829 OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
830 OSSL_PARAM_END
831 };
832 return known_settable_ctx_params;
833 }
834
835 const OSSL_DISPATCH ossl_drbg_ctr_functions[] = {
836 { OSSL_FUNC_RAND_NEWCTX, (void (*)(void))drbg_ctr_new_wrapper },
837 { OSSL_FUNC_RAND_FREECTX, (void (*)(void))drbg_ctr_free },
838 { OSSL_FUNC_RAND_INSTANTIATE,
839 (void (*)(void))drbg_ctr_instantiate_wrapper },
840 { OSSL_FUNC_RAND_UNINSTANTIATE,
841 (void (*)(void))drbg_ctr_uninstantiate_wrapper },
842 { OSSL_FUNC_RAND_GENERATE, (void (*)(void))drbg_ctr_generate_wrapper },
843 { OSSL_FUNC_RAND_RESEED, (void (*)(void))drbg_ctr_reseed_wrapper },
844 { OSSL_FUNC_RAND_ENABLE_LOCKING, (void (*)(void))ossl_drbg_enable_locking },
845 { OSSL_FUNC_RAND_LOCK, (void (*)(void))ossl_drbg_lock },
846 { OSSL_FUNC_RAND_UNLOCK, (void (*)(void))ossl_drbg_unlock },
847 { OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS,
848 (void (*)(void))drbg_ctr_settable_ctx_params },
849 { OSSL_FUNC_RAND_SET_CTX_PARAMS, (void (*)(void))drbg_ctr_set_ctx_params },
850 { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
851 (void (*)(void))drbg_ctr_gettable_ctx_params },
852 { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void (*)(void))drbg_ctr_get_ctx_params },
853 { OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
854 (void (*)(void))drbg_ctr_verify_zeroization },
855 { OSSL_FUNC_RAND_GET_SEED, (void (*)(void))ossl_drbg_get_seed },
856 { OSSL_FUNC_RAND_CLEAR_SEED, (void (*)(void))ossl_drbg_clear_seed },
857 OSSL_DISPATCH_END
858 };
859