]> git.ipfire.org Git - thirdparty/openssl.git/blame - providers/implementations/rands/drbg_ctr.c
Move e_os.h to include/internal
[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>
d5f9166b 17#include "internal/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
f000e828
P
499 /* Maximum number of bits per request = 2^19 = 2^16 bytes */
500 drbg->max_request = 1 << 16;
501 if (ctr->use_df) {
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;
57ca171a 508
f000e828
P
509 if (ctr->keylen > 0) {
510 drbg->min_entropylen = ctr->keylen;
511 drbg->min_noncelen = drbg->min_entropylen / 2;
512 }
513 } else {
514 const size_t len = ctr->keylen > 0 ? drbg->seedlen : DRBG_MAX_LENGTH;
515
516 drbg->min_entropylen = len;
517 drbg->max_entropylen = len;
518 /* Nonce not used */
519 drbg->min_noncelen = 0;
520 drbg->max_noncelen = 0;
521 drbg->max_perslen = len;
522 drbg->max_adinlen = len;
523 }
524 return res;
525}
526
527static int drbg_ctr_init(PROV_DRBG *drbg)
528{
529 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
2f142901 530 size_t keylen;
8212d505 531
2f142901
P
532 if (ctr->cipher_ctr == NULL) {
533 ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
534 return 0;
535 }
ed576acd 536 ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
28bdbe1a
PS
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();
f000e828
P
541 if (ctr->ctx_ecb == NULL || ctr->ctx_ctr == NULL) {
542 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
543 goto err;
544 }
545
2f142901
P
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);
551 goto err;
552 }
f000e828 553
2f142901
P
554 drbg->strength = keylen * 8;
555 drbg->seedlen = keylen + 16;
f000e828 556
2f142901
P
557 if (ctr->use_df) {
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
564 };
565
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);
570 goto err;
571 }
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);
576 goto err;
f000e828
P
577 }
578 }
579 return drbg_ctr_init_lengths(drbg);
580
581err:
582 EVP_CIPHER_CTX_free(ctr->ctx_ecb);
583 EVP_CIPHER_CTX_free(ctr->ctx_ctr);
584 ctr->ctx_ecb = ctr->ctx_ctr = NULL;
585 return 0;
586}
587
588static int drbg_ctr_new(PROV_DRBG *drbg)
589{
590 PROV_DRBG_CTR *ctr;
591
592 ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
593 if (ctr == NULL) {
594 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
dbdcc04f 595 return 0;
f000e828
P
596 }
597
598 ctr->use_df = 1;
599 drbg->data = ctr;
600 return drbg_ctr_init_lengths(drbg);
601}
602
603static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
604 const OSSL_DISPATCH *parent_dispatch)
605{
1dc188ba 606 return ossl_rand_drbg_new(provctx, parent, parent_dispatch, &drbg_ctr_new,
f000e828
P
607 &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
608 &drbg_ctr_reseed, &drbg_ctr_generate);
609}
610
611static void drbg_ctr_free(void *vdrbg)
612{
613 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
614 PROV_DRBG_CTR *ctr;
615
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);
622
623 OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
624 }
1dc188ba 625 ossl_rand_drbg_free(drbg);
f000e828
P
626}
627
628static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
629{
630 PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
0ed26fb6
P
631 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
632 OSSL_PARAM *p;
633
634 p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_USE_DF);
635 if (p != NULL && !OSSL_PARAM_set_int(p, ctr->use_df))
636 return 0;
637
638 p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_CIPHER);
639 if (p != NULL) {
640 if (ctr->cipher_ctr == NULL
ed576acd
TM
641 || !OSSL_PARAM_set_utf8_string(p,
642 EVP_CIPHER_get0_name(ctr->cipher_ctr)))
0ed26fb6
P
643 return 0;
644 }
f000e828 645
b24d6c33 646 return ossl_drbg_get_ctx_params(drbg, params);
f000e828
P
647}
648
a3f091fd
P
649static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *vctx,
650 ossl_unused void *provctx)
f000e828
P
651{
652 static const OSSL_PARAM known_gettable_ctx_params[] = {
0ed26fb6
P
653 OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
654 OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
82a7b2fb 655 OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON,
f000e828
P
656 OSSL_PARAM_END
657 };
658 return known_gettable_ctx_params;
659}
660
661static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[])
662{
663 PROV_DRBG *ctx = (PROV_DRBG *)vctx;
664 PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
a829b735 665 OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
f000e828
P
666 const OSSL_PARAM *p;
667 char *ecb;
668 const char *propquery = NULL;
669 int i, cipher_init = 0;
670
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;
675 cipher_init = 1;
676 }
677
678 if ((p = OSSL_PARAM_locate_const(params,
679 OSSL_DRBG_PARAM_PROPERTIES)) != NULL) {
680 if (p->data_type != OSSL_PARAM_UTF8_STRING)
681 return 0;
682 propquery = (const char *)p->data;
683 }
684
685 if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_CIPHER)) != NULL) {
686 const char *base = (const char *)p->data;
3262300a
RL
687 size_t ctr_str_len = sizeof("CTR") - 1;
688 size_t ecb_str_len = sizeof("ECB") - 1;
28bdbe1a 689
f000e828 690 if (p->data_type != OSSL_PARAM_UTF8_STRING
3262300a 691 || p->data_size < ctr_str_len)
dbdcc04f 692 return 0;
3262300a 693 if (strcasecmp("CTR", base + p->data_size - ctr_str_len) != 0) {
f000e828
P
694 ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
695 return 0;
696 }
3262300a 697 if ((ecb = OPENSSL_strndup(base, p->data_size)) == NULL) {
f000e828 698 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
dbdcc04f 699 return 0;
f000e828 700 }
3262300a 701 strcpy(ecb + p->data_size - ecb_str_len, "ECB");
f000e828
P
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);
706 OPENSSL_free(ecb);
707 if (ctr->cipher_ctr == NULL || ctr->cipher_ecb == NULL) {
708 ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_FIND_CIPHERS);
709 return 0;
710 }
711 cipher_init = 1;
712 }
75e2c877 713
f000e828 714 if (cipher_init && !drbg_ctr_init(ctx))
6c7d80ab 715 return 0;
12fb8c3d 716
b24d6c33 717 return ossl_drbg_set_ctx_params(ctx, params);
f000e828 718}
4917e911 719
a3f091fd
P
720static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
721 ossl_unused void *provctx)
f000e828
P
722{
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),
f000e828 726 OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
82a7b2fb 727 OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
f000e828
P
728 OSSL_PARAM_END
729 };
730 return known_settable_ctx_params;
12fb8c3d 731}
f000e828 732
1be63951 733const OSSL_DISPATCH ossl_drbg_ctr_functions[] = {
f000e828
P
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 },
b24d6c33
P
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 },
f000e828
P
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 },
f000e828
P
751 { OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
752 (void(*)(void))drbg_ctr_verify_zeroization },
335e85f5
P
753 { OSSL_FUNC_RAND_GET_SEED, (void(*)(void))ossl_drbg_get_seed },
754 { OSSL_FUNC_RAND_CLEAR_SEED, (void(*)(void))ossl_drbg_clear_seed },
f000e828
P
755 { 0, NULL }
756};