Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/openssl/providers/implementations/rands/drbg_ctr.c
48383 views
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
*/
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
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
*/
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
*/
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
*/
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
*/
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
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
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
*/
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
859