Coverage Report

Created: 2025-12-04 06:33

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