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