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