2 * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved.
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
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 "e_os.h" /* strcasecmp */
18 #include "crypto/modes.h"
19 #include "internal/thread_once.h"
20 #include "prov/implementations.h"
21 #include "prov/providercommon.h"
22 #include "prov/provider_ctx.h"
23 #include "drbg_local.h"
25 static OSSL_FUNC_rand_newctx_fn drbg_ctr_new_wrapper
;
26 static OSSL_FUNC_rand_freectx_fn drbg_ctr_free
;
27 static OSSL_FUNC_rand_instantiate_fn drbg_ctr_instantiate_wrapper
;
28 static OSSL_FUNC_rand_uninstantiate_fn drbg_ctr_uninstantiate_wrapper
;
29 static OSSL_FUNC_rand_generate_fn drbg_ctr_generate_wrapper
;
30 static OSSL_FUNC_rand_reseed_fn drbg_ctr_reseed_wrapper
;
31 static OSSL_FUNC_rand_settable_ctx_params_fn drbg_ctr_settable_ctx_params
;
32 static OSSL_FUNC_rand_set_ctx_params_fn drbg_ctr_set_ctx_params
;
33 static OSSL_FUNC_rand_gettable_ctx_params_fn drbg_ctr_gettable_ctx_params
;
34 static OSSL_FUNC_rand_get_ctx_params_fn drbg_ctr_get_ctx_params
;
35 static OSSL_FUNC_rand_verify_zeroization_fn drbg_ctr_verify_zeroization
;
38 * The state of a DRBG AES-CTR.
40 typedef struct rand_drbg_ctr_st
{
41 EVP_CIPHER_CTX
*ctx_ecb
;
42 EVP_CIPHER_CTX
*ctx_ctr
;
43 EVP_CIPHER_CTX
*ctx_df
;
44 EVP_CIPHER
*cipher_ecb
;
45 EVP_CIPHER
*cipher_ctr
;
50 /* Temporary block storage used by ctr_df */
51 unsigned char bltmp
[16];
57 * Implementation of NIST SP 800-90A CTR DRBG.
59 static void inc_128(PROV_DRBG_CTR
*ctr
)
61 unsigned char *p
= &ctr
->V
[0];
72 static void ctr_XOR(PROV_DRBG_CTR
*ctr
, const unsigned char *in
, size_t inlen
)
76 if (in
== NULL
|| inlen
== 0)
80 * Any zero padding will have no effect on the result as we
81 * are XORing. So just process however much input we have.
83 n
= inlen
< ctr
->keylen
? inlen
: ctr
->keylen
;
84 for (i
= 0; i
< n
; i
++)
86 if (inlen
<= ctr
->keylen
)
89 n
= inlen
- ctr
->keylen
;
91 /* Should never happen */
94 for (i
= 0; i
< n
; i
++)
95 ctr
->V
[i
] ^= in
[i
+ ctr
->keylen
];
99 * Process a complete block using BCC algorithm of SP 800-90A 10.3.3
101 __owur
static int ctr_BCC_block(PROV_DRBG_CTR
*ctr
, unsigned char *out
,
102 const unsigned char *in
, int len
)
104 int i
, outlen
= AES_BLOCK_SIZE
;
106 for (i
= 0; i
< len
; i
++)
109 if (!EVP_CipherUpdate(ctr
->ctx_df
, out
, &outlen
, out
, len
)
117 * Handle several BCC operations for as much data as we need for K and X
119 __owur
static int ctr_BCC_blocks(PROV_DRBG_CTR
*ctr
, const unsigned char *in
)
121 unsigned char in_tmp
[48];
122 unsigned char num_of_blk
= 2;
124 memcpy(in_tmp
, in
, 16);
125 memcpy(in_tmp
+ 16, in
, 16);
126 if (ctr
->keylen
!= 16) {
127 memcpy(in_tmp
+ 32, in
, 16);
130 return ctr_BCC_block(ctr
, ctr
->KX
, in_tmp
, AES_BLOCK_SIZE
* num_of_blk
);
134 * Initialise BCC blocks: these have the value 0,1,2 in leftmost positions:
135 * see 10.3.1 stage 7.
137 __owur
static int ctr_BCC_init(PROV_DRBG_CTR
*ctr
)
139 unsigned char bltmp
[48] = {0};
140 unsigned char num_of_blk
;
142 memset(ctr
->KX
, 0, 48);
143 num_of_blk
= ctr
->keylen
== 16 ? 2 : 3;
144 bltmp
[(AES_BLOCK_SIZE
* 1) + 3] = 1;
145 bltmp
[(AES_BLOCK_SIZE
* 2) + 3] = 2;
146 return ctr_BCC_block(ctr
, ctr
->KX
, bltmp
, num_of_blk
* AES_BLOCK_SIZE
);
150 * Process several blocks into BCC algorithm, some possibly partial
152 __owur
static int ctr_BCC_update(PROV_DRBG_CTR
*ctr
,
153 const unsigned char *in
, size_t inlen
)
155 if (in
== NULL
|| inlen
== 0)
158 /* If we have partial block handle it first */
159 if (ctr
->bltmp_pos
) {
160 size_t left
= 16 - ctr
->bltmp_pos
;
162 /* If we now have a complete block process it */
164 memcpy(ctr
->bltmp
+ ctr
->bltmp_pos
, in
, left
);
165 if (!ctr_BCC_blocks(ctr
, ctr
->bltmp
))
173 /* Process zero or more complete blocks */
174 for (; inlen
>= 16; in
+= 16, inlen
-= 16) {
175 if (!ctr_BCC_blocks(ctr
, in
))
179 /* Copy any remaining partial block to the temporary buffer */
181 memcpy(ctr
->bltmp
+ ctr
->bltmp_pos
, in
, inlen
);
182 ctr
->bltmp_pos
+= inlen
;
187 __owur
static int ctr_BCC_final(PROV_DRBG_CTR
*ctr
)
189 if (ctr
->bltmp_pos
) {
190 memset(ctr
->bltmp
+ ctr
->bltmp_pos
, 0, 16 - ctr
->bltmp_pos
);
191 if (!ctr_BCC_blocks(ctr
, ctr
->bltmp
))
197 __owur
static int ctr_df(PROV_DRBG_CTR
*ctr
,
198 const unsigned char *in1
, size_t in1len
,
199 const unsigned char *in2
, size_t in2len
,
200 const unsigned char *in3
, size_t in3len
)
202 static unsigned char c80
= 0x80;
204 unsigned char *p
= ctr
->bltmp
;
205 int outlen
= AES_BLOCK_SIZE
;
207 if (!ctr_BCC_init(ctr
))
215 inlen
= in1len
+ in2len
+ in3len
;
216 /* Initialise L||N in temporary block */
217 *p
++ = (inlen
>> 24) & 0xff;
218 *p
++ = (inlen
>> 16) & 0xff;
219 *p
++ = (inlen
>> 8) & 0xff;
222 /* NB keylen is at most 32 bytes */
226 *p
= (unsigned char)((ctr
->keylen
+ 16) & 0xff);
228 if (!ctr_BCC_update(ctr
, in1
, in1len
)
229 || !ctr_BCC_update(ctr
, in2
, in2len
)
230 || !ctr_BCC_update(ctr
, in3
, in3len
)
231 || !ctr_BCC_update(ctr
, &c80
, 1)
232 || !ctr_BCC_final(ctr
))
235 if (!EVP_CipherInit_ex(ctr
->ctx_ecb
, NULL
, NULL
, ctr
->KX
, NULL
, -1))
237 /* X follows key K */
238 if (!EVP_CipherUpdate(ctr
->ctx_ecb
, ctr
->KX
, &outlen
, ctr
->KX
+ ctr
->keylen
,
240 || outlen
!= AES_BLOCK_SIZE
)
242 if (!EVP_CipherUpdate(ctr
->ctx_ecb
, ctr
->KX
+ 16, &outlen
, ctr
->KX
,
244 || outlen
!= AES_BLOCK_SIZE
)
246 if (ctr
->keylen
!= 16)
247 if (!EVP_CipherUpdate(ctr
->ctx_ecb
, ctr
->KX
+ 32, &outlen
,
248 ctr
->KX
+ 16, AES_BLOCK_SIZE
)
249 || outlen
!= AES_BLOCK_SIZE
)
255 * NB the no-df Update in SP800-90A specifies a constant input length
256 * of seedlen, however other uses of this algorithm pad the input with
257 * zeroes if necessary and have up to two parameters XORed together,
258 * so we handle both cases in this function instead.
260 __owur
static int ctr_update(PROV_DRBG
*drbg
,
261 const unsigned char *in1
, size_t in1len
,
262 const unsigned char *in2
, size_t in2len
,
263 const unsigned char *nonce
, size_t noncelen
)
265 PROV_DRBG_CTR
*ctr
= (PROV_DRBG_CTR
*)drbg
->data
;
266 int outlen
= AES_BLOCK_SIZE
;
267 unsigned char V_tmp
[48], out
[48];
270 /* correct key is already set up. */
271 memcpy(V_tmp
, ctr
->V
, 16);
273 memcpy(V_tmp
+ 16, ctr
->V
, 16);
274 if (ctr
->keylen
== 16) {
278 memcpy(V_tmp
+ 32, ctr
->V
, 16);
281 if (!EVP_CipherUpdate(ctr
->ctx_ecb
, out
, &outlen
, V_tmp
, len
)
284 memcpy(ctr
->K
, out
, ctr
->keylen
);
285 memcpy(ctr
->V
, out
+ ctr
->keylen
, 16);
288 /* If no input reuse existing derived value */
289 if (in1
!= NULL
|| nonce
!= NULL
|| in2
!= NULL
)
290 if (!ctr_df(ctr
, in1
, in1len
, nonce
, noncelen
, in2
, in2len
))
292 /* If this a reuse input in1len != 0 */
294 ctr_XOR(ctr
, ctr
->KX
, drbg
->seedlen
);
296 ctr_XOR(ctr
, in1
, in1len
);
297 ctr_XOR(ctr
, in2
, in2len
);
300 if (!EVP_CipherInit_ex(ctr
->ctx_ecb
, NULL
, NULL
, ctr
->K
, NULL
, -1)
301 || !EVP_CipherInit_ex(ctr
->ctx_ctr
, NULL
, NULL
, ctr
->K
, NULL
, -1))
306 static int drbg_ctr_instantiate(PROV_DRBG
*drbg
,
307 const unsigned char *entropy
, size_t entropylen
,
308 const unsigned char *nonce
, size_t noncelen
,
309 const unsigned char *pers
, size_t perslen
)
311 PROV_DRBG_CTR
*ctr
= (PROV_DRBG_CTR
*)drbg
->data
;
316 memset(ctr
->K
, 0, sizeof(ctr
->K
));
317 memset(ctr
->V
, 0, sizeof(ctr
->V
));
318 if (!EVP_CipherInit_ex(ctr
->ctx_ecb
, NULL
, NULL
, ctr
->K
, NULL
, -1))
322 if (!ctr_update(drbg
, entropy
, entropylen
, pers
, perslen
, nonce
, noncelen
))
327 static int drbg_ctr_instantiate_wrapper(void *vdrbg
, unsigned int strength
,
328 int prediction_resistance
,
329 const unsigned char *pstr
,
331 const OSSL_PARAM params
[])
333 PROV_DRBG
*drbg
= (PROV_DRBG
*)vdrbg
;
335 if (!ossl_prov_is_running() || !drbg_ctr_set_ctx_params(drbg
, params
))
337 return ossl_prov_drbg_instantiate(drbg
, strength
, prediction_resistance
,
341 static int drbg_ctr_reseed(PROV_DRBG
*drbg
,
342 const unsigned char *entropy
, size_t entropylen
,
343 const unsigned char *adin
, size_t adinlen
)
345 PROV_DRBG_CTR
*ctr
= (PROV_DRBG_CTR
*)drbg
->data
;
351 if (!ctr_update(drbg
, entropy
, entropylen
, adin
, adinlen
, NULL
, 0))
356 static int drbg_ctr_reseed_wrapper(void *vdrbg
, int prediction_resistance
,
357 const unsigned char *ent
, size_t ent_len
,
358 const unsigned char *adin
, size_t adin_len
)
360 PROV_DRBG
*drbg
= (PROV_DRBG
*)vdrbg
;
362 return ossl_prov_drbg_reseed(drbg
, prediction_resistance
, ent
, ent_len
,
366 static void ctr96_inc(unsigned char *counter
)
378 static int drbg_ctr_generate(PROV_DRBG
*drbg
,
379 unsigned char *out
, size_t outlen
,
380 const unsigned char *adin
, size_t adinlen
)
382 PROV_DRBG_CTR
*ctr
= (PROV_DRBG_CTR
*)drbg
->data
;
383 unsigned int ctr32
, blocks
;
386 if (adin
!= NULL
&& adinlen
!= 0) {
389 if (!ctr_update(drbg
, adin
, adinlen
, NULL
, 0, NULL
, 0))
391 /* This means we reuse derived value */
405 if (!ctr_update(drbg
, adin
, adinlen
, NULL
, 0, NULL
, 0))
410 memset(out
, 0, outlen
);
413 if (!EVP_CipherInit_ex(ctr
->ctx_ctr
,
414 NULL
, NULL
, NULL
, ctr
->V
, -1))
418 * outlen has type size_t while EVP_CipherUpdate takes an
419 * int argument and thus cannot be guaranteed to process more
420 * than 2^31-1 bytes at a time. We process such huge generate
421 * requests in 2^30 byte chunks, which is the greatest multiple
422 * of AES block size lower than or equal to 2^31-1.
424 buflen
= outlen
> (1U << 30) ? (1U << 30) : outlen
;
425 blocks
= (buflen
+ 15) / 16;
427 ctr32
= GETU32(ctr
->V
+ 12) + blocks
;
428 if (ctr32
< blocks
) {
429 /* 32-bit counter overflow into V. */
432 buflen
= blocks
* 16;
437 PUTU32(ctr
->V
+ 12, ctr32
);
439 if (!EVP_CipherUpdate(ctr
->ctx_ctr
, out
, &outl
, out
, buflen
)
447 if (!ctr_update(drbg
, adin
, adinlen
, NULL
, 0, NULL
, 0))
452 static int drbg_ctr_generate_wrapper
453 (void *vdrbg
, unsigned char *out
, size_t outlen
,
454 unsigned int strength
, int prediction_resistance
,
455 const unsigned char *adin
, size_t adin_len
)
457 PROV_DRBG
*drbg
= (PROV_DRBG
*)vdrbg
;
459 return ossl_prov_drbg_generate(drbg
, out
, outlen
, strength
,
460 prediction_resistance
, adin
, adin_len
);
463 static int drbg_ctr_uninstantiate(PROV_DRBG
*drbg
)
465 PROV_DRBG_CTR
*ctr
= (PROV_DRBG_CTR
*)drbg
->data
;
467 OPENSSL_cleanse(ctr
->K
, sizeof(ctr
->K
));
468 OPENSSL_cleanse(ctr
->V
, sizeof(ctr
->V
));
469 OPENSSL_cleanse(ctr
->bltmp
, sizeof(ctr
->bltmp
));
470 OPENSSL_cleanse(ctr
->KX
, sizeof(ctr
->KX
));
472 return ossl_prov_drbg_uninstantiate(drbg
);
475 static int drbg_ctr_uninstantiate_wrapper(void *vdrbg
)
477 return drbg_ctr_uninstantiate((PROV_DRBG
*)vdrbg
);
480 static int drbg_ctr_verify_zeroization(void *vdrbg
)
482 PROV_DRBG
*drbg
= (PROV_DRBG
*)vdrbg
;
483 PROV_DRBG_CTR
*ctr
= (PROV_DRBG_CTR
*)drbg
->data
;
485 PROV_DRBG_VERYIFY_ZEROIZATION(ctr
->K
);
486 PROV_DRBG_VERYIFY_ZEROIZATION(ctr
->V
);
487 PROV_DRBG_VERYIFY_ZEROIZATION(ctr
->bltmp
);
488 PROV_DRBG_VERYIFY_ZEROIZATION(ctr
->KX
);
489 if (ctr
->bltmp_pos
!= 0)
494 static int drbg_ctr_init_lengths(PROV_DRBG
*drbg
)
496 PROV_DRBG_CTR
*ctr
= (PROV_DRBG_CTR
*)drbg
->data
;
499 /* Maximum number of bits per request = 2^19 = 2^16 bytes */
500 drbg
->max_request
= 1 << 16;
502 drbg
->min_entropylen
= 0;
503 drbg
->max_entropylen
= DRBG_MAX_LENGTH
;
504 drbg
->min_noncelen
= 0;
505 drbg
->max_noncelen
= DRBG_MAX_LENGTH
;
506 drbg
->max_perslen
= DRBG_MAX_LENGTH
;
507 drbg
->max_adinlen
= DRBG_MAX_LENGTH
;
509 if (ctr
->keylen
> 0) {
510 drbg
->min_entropylen
= ctr
->keylen
;
511 drbg
->min_noncelen
= drbg
->min_entropylen
/ 2;
514 const size_t len
= ctr
->keylen
> 0 ? drbg
->seedlen
: DRBG_MAX_LENGTH
;
516 drbg
->min_entropylen
= len
;
517 drbg
->max_entropylen
= len
;
519 drbg
->min_noncelen
= 0;
520 drbg
->max_noncelen
= 0;
521 drbg
->max_perslen
= len
;
522 drbg
->max_adinlen
= len
;
527 static int drbg_ctr_init(PROV_DRBG
*drbg
)
529 PROV_DRBG_CTR
*ctr
= (PROV_DRBG_CTR
*)drbg
->data
;
532 if (ctr
->cipher_ctr
== NULL
) {
533 ERR_raise(ERR_LIB_PROV
, PROV_R_MISSING_CIPHER
);
536 ctr
->keylen
= keylen
= EVP_CIPHER_get_key_length(ctr
->cipher_ctr
);
537 if (ctr
->ctx_ecb
== NULL
)
538 ctr
->ctx_ecb
= EVP_CIPHER_CTX_new();
539 if (ctr
->ctx_ctr
== NULL
)
540 ctr
->ctx_ctr
= EVP_CIPHER_CTX_new();
541 if (ctr
->ctx_ecb
== NULL
|| ctr
->ctx_ctr
== NULL
) {
542 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
546 if (!EVP_CipherInit_ex(ctr
->ctx_ecb
,
547 ctr
->cipher_ecb
, NULL
, NULL
, NULL
, 1)
548 || !EVP_CipherInit_ex(ctr
->ctx_ctr
,
549 ctr
->cipher_ctr
, NULL
, NULL
, NULL
, 1)) {
550 ERR_raise(ERR_LIB_PROV
, PROV_R_UNABLE_TO_INITIALISE_CIPHERS
);
554 drbg
->strength
= keylen
* 8;
555 drbg
->seedlen
= keylen
+ 16;
558 /* df initialisation */
559 static const unsigned char df_key
[32] = {
560 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
561 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
562 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
563 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
566 if (ctr
->ctx_df
== NULL
)
567 ctr
->ctx_df
= EVP_CIPHER_CTX_new();
568 if (ctr
->ctx_df
== NULL
) {
569 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
572 /* Set key schedule for df_key */
573 if (!EVP_CipherInit_ex(ctr
->ctx_df
,
574 ctr
->cipher_ecb
, NULL
, df_key
, NULL
, 1)) {
575 ERR_raise(ERR_LIB_PROV
, PROV_R_DERIVATION_FUNCTION_INIT_FAILED
);
579 return drbg_ctr_init_lengths(drbg
);
582 EVP_CIPHER_CTX_free(ctr
->ctx_ecb
);
583 EVP_CIPHER_CTX_free(ctr
->ctx_ctr
);
584 ctr
->ctx_ecb
= ctr
->ctx_ctr
= NULL
;
588 static int drbg_ctr_new(PROV_DRBG
*drbg
)
592 ctr
= OPENSSL_secure_zalloc(sizeof(*ctr
));
594 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
600 return drbg_ctr_init_lengths(drbg
);
603 static void *drbg_ctr_new_wrapper(void *provctx
, void *parent
,
604 const OSSL_DISPATCH
*parent_dispatch
)
606 return ossl_rand_drbg_new(provctx
, parent
, parent_dispatch
, &drbg_ctr_new
,
607 &drbg_ctr_instantiate
, &drbg_ctr_uninstantiate
,
608 &drbg_ctr_reseed
, &drbg_ctr_generate
);
611 static void drbg_ctr_free(void *vdrbg
)
613 PROV_DRBG
*drbg
= (PROV_DRBG
*)vdrbg
;
616 if (drbg
!= NULL
&& (ctr
= (PROV_DRBG_CTR
*)drbg
->data
) != NULL
) {
617 EVP_CIPHER_CTX_free(ctr
->ctx_ecb
);
618 EVP_CIPHER_CTX_free(ctr
->ctx_ctr
);
619 EVP_CIPHER_CTX_free(ctr
->ctx_df
);
620 EVP_CIPHER_free(ctr
->cipher_ecb
);
621 EVP_CIPHER_free(ctr
->cipher_ctr
);
623 OPENSSL_secure_clear_free(ctr
, sizeof(*ctr
));
625 ossl_rand_drbg_free(drbg
);
628 static int drbg_ctr_get_ctx_params(void *vdrbg
, OSSL_PARAM params
[])
630 PROV_DRBG
*drbg
= (PROV_DRBG
*)vdrbg
;
631 PROV_DRBG_CTR
*ctr
= (PROV_DRBG_CTR
*)drbg
->data
;
634 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_USE_DF
);
635 if (p
!= NULL
&& !OSSL_PARAM_set_int(p
, ctr
->use_df
))
638 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_CIPHER
);
640 if (ctr
->cipher_ctr
== NULL
641 || !OSSL_PARAM_set_utf8_string(p
,
642 EVP_CIPHER_get0_name(ctr
->cipher_ctr
)))
646 return ossl_drbg_get_ctx_params(drbg
, params
);
649 static const OSSL_PARAM
*drbg_ctr_gettable_ctx_params(ossl_unused
void *vctx
,
650 ossl_unused
void *provctx
)
652 static const OSSL_PARAM known_gettable_ctx_params
[] = {
653 OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER
, NULL
, 0),
654 OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF
, NULL
),
655 OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON
,
658 return known_gettable_ctx_params
;
661 static int drbg_ctr_set_ctx_params(void *vctx
, const OSSL_PARAM params
[])
663 PROV_DRBG
*ctx
= (PROV_DRBG
*)vctx
;
664 PROV_DRBG_CTR
*ctr
= (PROV_DRBG_CTR
*)ctx
->data
;
665 OSSL_LIB_CTX
*libctx
= PROV_LIBCTX_OF(ctx
->provctx
);
668 const char *propquery
= NULL
;
669 int i
, cipher_init
= 0;
671 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_DRBG_PARAM_USE_DF
)) != NULL
672 && OSSL_PARAM_get_int(p
, &i
)) {
673 /* FIPS errors out in the drbg_ctr_init() call later */
674 ctr
->use_df
= i
!= 0;
678 if ((p
= OSSL_PARAM_locate_const(params
,
679 OSSL_DRBG_PARAM_PROPERTIES
)) != NULL
) {
680 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
)
682 propquery
= (const char *)p
->data
;
685 if ((p
= OSSL_PARAM_locate_const(params
, OSSL_DRBG_PARAM_CIPHER
)) != NULL
) {
686 const char *base
= (const char *)p
->data
;
687 size_t ctr_str_len
= sizeof("CTR") - 1;
688 size_t ecb_str_len
= sizeof("ECB") - 1;
690 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
691 || p
->data_size
< ctr_str_len
)
693 if (strcasecmp("CTR", base
+ p
->data_size
- ctr_str_len
) != 0) {
694 ERR_raise(ERR_LIB_PROV
, PROV_R_REQUIRE_CTR_MODE_CIPHER
);
697 if ((ecb
= OPENSSL_strndup(base
, p
->data_size
)) == NULL
) {
698 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
701 strcpy(ecb
+ p
->data_size
- ecb_str_len
, "ECB");
702 EVP_CIPHER_free(ctr
->cipher_ecb
);
703 EVP_CIPHER_free(ctr
->cipher_ctr
);
704 ctr
->cipher_ctr
= EVP_CIPHER_fetch(libctx
, base
, propquery
);
705 ctr
->cipher_ecb
= EVP_CIPHER_fetch(libctx
, ecb
, propquery
);
707 if (ctr
->cipher_ctr
== NULL
|| ctr
->cipher_ecb
== NULL
) {
708 ERR_raise(ERR_LIB_PROV
, PROV_R_UNABLE_TO_FIND_CIPHERS
);
714 if (cipher_init
&& !drbg_ctr_init(ctx
))
717 return ossl_drbg_set_ctx_params(ctx
, params
);
720 static const OSSL_PARAM
*drbg_ctr_settable_ctx_params(ossl_unused
void *vctx
,
721 ossl_unused
void *provctx
)
723 static const OSSL_PARAM known_settable_ctx_params
[] = {
724 OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES
, NULL
, 0),
725 OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER
, NULL
, 0),
726 OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF
, NULL
),
727 OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON
,
730 return known_settable_ctx_params
;
733 const OSSL_DISPATCH ossl_drbg_ctr_functions
[] = {
734 { OSSL_FUNC_RAND_NEWCTX
, (void(*)(void))drbg_ctr_new_wrapper
},
735 { OSSL_FUNC_RAND_FREECTX
, (void(*)(void))drbg_ctr_free
},
736 { OSSL_FUNC_RAND_INSTANTIATE
,
737 (void(*)(void))drbg_ctr_instantiate_wrapper
},
738 { OSSL_FUNC_RAND_UNINSTANTIATE
,
739 (void(*)(void))drbg_ctr_uninstantiate_wrapper
},
740 { OSSL_FUNC_RAND_GENERATE
, (void(*)(void))drbg_ctr_generate_wrapper
},
741 { OSSL_FUNC_RAND_RESEED
, (void(*)(void))drbg_ctr_reseed_wrapper
},
742 { OSSL_FUNC_RAND_ENABLE_LOCKING
, (void(*)(void))ossl_drbg_enable_locking
},
743 { OSSL_FUNC_RAND_LOCK
, (void(*)(void))ossl_drbg_lock
},
744 { OSSL_FUNC_RAND_UNLOCK
, (void(*)(void))ossl_drbg_unlock
},
745 { OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS
,
746 (void(*)(void))drbg_ctr_settable_ctx_params
},
747 { OSSL_FUNC_RAND_SET_CTX_PARAMS
, (void(*)(void))drbg_ctr_set_ctx_params
},
748 { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS
,
749 (void(*)(void))drbg_ctr_gettable_ctx_params
},
750 { OSSL_FUNC_RAND_GET_CTX_PARAMS
, (void(*)(void))drbg_ctr_get_ctx_params
},
751 { OSSL_FUNC_RAND_VERIFY_ZEROIZATION
,
752 (void(*)(void))drbg_ctr_verify_zeroization
},
753 { OSSL_FUNC_RAND_GET_SEED
, (void(*)(void))ossl_drbg_get_seed
},
754 { OSSL_FUNC_RAND_CLEAR_SEED
, (void(*)(void))ossl_drbg_clear_seed
},