Coverage Report

Created: 2025-11-16 06:40

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
222k
{
61
222k
    unsigned char *p = &ctr->V[0];
62
222k
    u32 n = 16, c = 1;
63
64
3.55M
    do {
65
3.55M
        --n;
66
3.55M
        c += p[n];
67
3.55M
        p[n] = (u8)c;
68
3.55M
        c >>= 8;
69
3.55M
    } while (n);
70
222k
}
71
72
static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
73
46.8k
{
74
46.8k
    size_t i, n;
75
76
46.8k
    if (in == NULL || inlen == 0)
77
46.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
129
    n = inlen < ctr->keylen ? inlen : ctr->keylen;
84
129
    if (!ossl_assert(n <= sizeof(ctr->K)))
85
0
        return;
86
4.25k
    for (i = 0; i < n; i++)
87
4.12k
        ctr->K[i] ^= in[i];
88
129
    if (inlen <= ctr->keylen)
89
2
        return;
90
91
127
    n = inlen - ctr->keylen;
92
127
    if (n > 16) {
93
        /* Should never happen */
94
0
        n = 16;
95
0
    }
96
2.15k
    for (i = 0; i < n; i++)
97
2.03k
        ctr->V[i] ^= in[i + ctr->keylen];
98
127
}
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
392
{
106
392
    int i, outlen = AES_BLOCK_SIZE;
107
108
19.2k
    for (i = 0; i < len; i++)
109
18.8k
        out[i] ^= in[i];
110
111
392
    if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
112
392
        || outlen != len)
113
0
        return 0;
114
392
    return 1;
115
392
}
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
307
{
123
307
    unsigned char in_tmp[48];
124
307
    unsigned char num_of_blk = 2;
125
126
307
    memcpy(in_tmp, in, 16);
127
307
    memcpy(in_tmp + 16, in, 16);
128
307
    if (ctr->keylen != 16) {
129
307
        memcpy(in_tmp + 32, in, 16);
130
307
        num_of_blk = 3;
131
307
    }
132
307
    return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
133
307
}
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
85
{
141
85
    unsigned char bltmp[48] = {0};
142
85
    unsigned char num_of_blk;
143
144
85
    memset(ctr->KX, 0, 48);
145
85
    num_of_blk = ctr->keylen == 16 ? 2 : 3;
146
85
    bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
147
85
    bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
148
85
    return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
149
85
}
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
340
{
157
340
    if (in == NULL || inlen == 0)
158
140
        return 1;
159
160
    /* If we have partial block handle it first */
161
200
    if (ctr->bltmp_pos) {
162
162
        size_t left = 16 - ctr->bltmp_pos;
163
164
        /* If we now have a complete block process it */
165
162
        if (inlen >= left) {
166
115
            memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
167
115
            if (!ctr_BCC_blocks(ctr, ctr->bltmp))
168
0
                return 0;
169
115
            ctr->bltmp_pos = 0;
170
115
            inlen -= left;
171
115
            in += left;
172
115
        }
173
162
    }
174
175
    /* Process zero or more complete blocks */
176
307
    for (; inlen >= 16; in += 16, inlen -= 16) {
177
107
        if (!ctr_BCC_blocks(ctr, in))
178
0
            return 0;
179
107
    }
180
181
    /* Copy any remaining partial block to the temporary buffer */
182
200
    if (inlen > 0) {
183
162
        memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
184
162
        ctr->bltmp_pos += inlen;
185
162
    }
186
200
    return 1;
187
200
}
188
189
__owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr)
190
85
{
191
85
    if (ctr->bltmp_pos) {
192
85
        memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
193
85
        if (!ctr_BCC_blocks(ctr, ctr->bltmp))
194
0
            return 0;
195
85
    }
196
85
    return 1;
197
85
}
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
85
{
204
85
    static unsigned char c80 = 0x80;
205
85
    size_t inlen;
206
85
    unsigned char *p = ctr->bltmp;
207
85
    int outlen = AES_BLOCK_SIZE;
208
209
85
    if (!ctr_BCC_init(ctr))
210
0
        return 0;
211
85
    if (in1 == NULL)
212
0
        in1len = 0;
213
85
    if (in2 == NULL)
214
85
        in2len = 0;
215
85
    if (in3 == NULL)
216
55
        in3len = 0;
217
85
    inlen = in1len + in2len + in3len;
218
    /* Initialise L||N in temporary block */
219
85
    *p++ = (inlen >> 24) & 0xff;
220
85
    *p++ = (inlen >> 16) & 0xff;
221
85
    *p++ = (inlen >> 8) & 0xff;
222
85
    *p++ = inlen & 0xff;
223
224
    /* NB keylen is at most 32 bytes */
225
85
    *p++ = 0;
226
85
    *p++ = 0;
227
85
    *p++ = 0;
228
85
    *p = (unsigned char)((ctr->keylen + 16) & 0xff);
229
85
    ctr->bltmp_pos = 8;
230
85
    if (!ctr_BCC_update(ctr, in1, in1len)
231
85
        || !ctr_BCC_update(ctr, in2, in2len)
232
85
        || !ctr_BCC_update(ctr, in3, in3len)
233
85
        || !ctr_BCC_update(ctr, &c80, 1)
234
85
        || !ctr_BCC_final(ctr))
235
0
        return 0;
236
    /* Set up key K */
237
85
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
238
0
        return 0;
239
    /* X follows key K */
240
85
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
241
85
                          AES_BLOCK_SIZE)
242
85
        || outlen != AES_BLOCK_SIZE)
243
0
        return 0;
244
85
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
245
85
                          AES_BLOCK_SIZE)
246
85
        || outlen != AES_BLOCK_SIZE)
247
0
        return 0;
248
85
    if (ctr->keylen != 16)
249
85
        if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
250
85
                              ctr->KX + 16, AES_BLOCK_SIZE)
251
85
            || outlen != AES_BLOCK_SIZE)
252
0
            return 0;
253
85
    return 1;
254
85
}
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
74.1k
{
267
74.1k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
268
74.1k
    int outlen = AES_BLOCK_SIZE;
269
74.1k
    unsigned char V_tmp[48], out[48];
270
74.1k
    unsigned char len;
271
272
    /* correct key is already set up. */
273
74.1k
    memcpy(V_tmp, ctr->V, 16);
274
74.1k
    inc_128(ctr);
275
74.1k
    memcpy(V_tmp + 16, ctr->V, 16);
276
74.1k
    if (ctr->keylen == 16) {
277
0
        len = 32;
278
74.1k
    } else {
279
74.1k
        inc_128(ctr);
280
74.1k
        memcpy(V_tmp + 32, ctr->V, 16);
281
74.1k
        len = 48;
282
74.1k
    }
283
74.1k
    if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
284
74.1k
            || outlen != len)
285
0
        return 0;
286
74.1k
    memcpy(ctr->K, out, ctr->keylen);
287
74.1k
    memcpy(ctr->V, out + ctr->keylen, 16);
288
289
74.1k
    if (ctr->use_df) {
290
        /* If no input reuse existing derived value */
291
50.8k
        if (in1 != NULL || nonce != NULL || in2 != NULL)
292
85
            if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
293
0
                return 0;
294
        /* If this a reuse input in1len != 0 */
295
50.8k
        if (in1len)
296
123
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
297
50.8k
    } else {
298
23.3k
        ctr_XOR(ctr, in1, in1len);
299
23.3k
        ctr_XOR(ctr, in2, in2len);
300
23.3k
    }
301
302
74.1k
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
303
74.1k
        || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
304
0
        return 0;
305
74.1k
    return 1;
306
74.1k
}
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
32
{
313
32
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
314
315
32
    if (entropy == NULL)
316
0
        return 0;
317
318
32
    memset(ctr->K, 0, sizeof(ctr->K));
319
32
    memset(ctr->V, 0, sizeof(ctr->V));
320
32
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
321
0
        return 0;
322
323
32
    inc_128(ctr);
324
32
    if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
325
0
        return 0;
326
32
    return 1;
327
32
}
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
19
{
347
19
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
348
349
19
    if (entropy == NULL)
350
0
        return 0;
351
352
19
    inc_128(ctr);
353
19
    if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
354
0
        return 0;
355
19
    return 1;
356
19
}
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
74.0k
{
384
74.0k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
385
74.0k
    unsigned int ctr32, blocks;
386
74.0k
    int outl, buflen;
387
388
74.0k
    if (adin != NULL && adinlen != 0) {
389
38
        inc_128(ctr);
390
391
38
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
392
0
            return 0;
393
        /* This means we reuse derived value */
394
38
        if (ctr->use_df) {
395
38
            adin = NULL;
396
38
            adinlen = 1;
397
38
        }
398
74.0k
    } else {
399
74.0k
        adinlen = 0;
400
74.0k
    }
401
402
74.0k
    inc_128(ctr);
403
404
74.0k
    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
74.0k
    memset(out, 0, outlen);
413
414
74.0k
    do {
415
74.0k
        if (!EVP_CipherInit_ex(ctr->ctx_ctr,
416
74.0k
                               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
74.0k
        buflen = outlen > (1U << 30) ? (1U << 30) : outlen;
427
74.0k
        blocks = (buflen + 15) / 16;
428
429
74.0k
        ctr32 = GETU32(ctr->V + 12) + blocks;
430
74.0k
        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
74.0k
        PUTU32(ctr->V + 12, ctr32);
440
441
74.0k
        if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
442
74.0k
            || outl != buflen)
443
0
            return 0;
444
445
74.0k
        out += buflen;
446
74.0k
        outlen -= buflen;
447
74.0k
    } while (outlen);
448
449
74.0k
    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
450
0
        return 0;
451
74.0k
    return 1;
452
74.0k
}
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
74.0k
{
459
74.0k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
460
461
74.0k
    return ossl_prov_drbg_generate(drbg, out, outlen, strength,
462
74.0k
                                   prediction_resistance, adin, adin_len);
463
74.0k
}
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
135
{
498
135
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
499
135
    int res = 1;
500
501
    /* Maximum number of bits per request = 2^19  = 2^16 bytes */
502
135
    drbg->max_request = 1 << 16;
503
135
    if (ctr->use_df) {
504
133
        drbg->min_entropylen = 0;
505
133
        drbg->max_entropylen = DRBG_MAX_LENGTH;
506
133
        drbg->min_noncelen = 0;
507
133
        drbg->max_noncelen = DRBG_MAX_LENGTH;
508
133
        drbg->max_perslen = DRBG_MAX_LENGTH;
509
133
        drbg->max_adinlen = DRBG_MAX_LENGTH;
510
511
133
        if (ctr->keylen > 0) {
512
30
            drbg->min_entropylen = ctr->keylen;
513
30
            drbg->min_noncelen = drbg->min_entropylen / 2;
514
30
        }
515
133
    } 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
135
    return res;
527
135
}
528
529
static int drbg_ctr_init(PROV_DRBG *drbg)
530
32
{
531
32
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
532
32
    size_t keylen;
533
534
32
    if (ctr->cipher_ctr == NULL) {
535
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
536
0
        return 0;
537
0
    }
538
32
    ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
539
32
    if (ctr->ctx_ecb == NULL)
540
32
        ctr->ctx_ecb = EVP_CIPHER_CTX_new();
541
32
    if (ctr->ctx_ctr == NULL)
542
32
        ctr->ctx_ctr = EVP_CIPHER_CTX_new();
543
32
    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
32
    if (!EVP_CipherInit_ex(ctr->ctx_ecb,
549
32
                           ctr->cipher_ecb, NULL, NULL, NULL, 1)
550
32
        || !EVP_CipherInit_ex(ctr->ctx_ctr,
551
32
                              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
32
    drbg->strength = keylen * 8;
557
32
    drbg->seedlen = keylen + 16;
558
559
32
    if (ctr->use_df) {
560
        /* df initialisation */
561
30
        static const unsigned char df_key[32] = {
562
30
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
563
30
            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
564
30
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
565
30
            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
566
30
        };
567
568
30
        if (ctr->ctx_df == NULL)
569
30
            ctr->ctx_df = EVP_CIPHER_CTX_new();
570
30
        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
30
        if (!EVP_CipherInit_ex(ctr->ctx_df,
576
30
                               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
30
    }
581
32
    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
32
}
589
590
static int drbg_ctr_new(PROV_DRBG *drbg)
591
103
{
592
103
    PROV_DRBG_CTR *ctr;
593
594
103
    ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
595
103
    if (ctr == NULL) {
596
0
        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
597
0
        return 0;
598
0
    }
599
600
103
    ctr->use_df = 1;
601
103
    drbg->data = ctr;
602
103
    return drbg_ctr_init_lengths(drbg);
603
103
}
604
605
static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
606
                                   const OSSL_DISPATCH *parent_dispatch)
607
103
{
608
103
    return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
609
103
                              &drbg_ctr_new, &drbg_ctr_free,
610
103
                              &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
611
103
                              &drbg_ctr_reseed, &drbg_ctr_generate);
612
103
}
613
614
static void drbg_ctr_free(void *vdrbg)
615
101
{
616
101
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
617
101
    PROV_DRBG_CTR *ctr;
618
619
101
    if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
620
101
        EVP_CIPHER_CTX_free(ctr->ctx_ecb);
621
101
        EVP_CIPHER_CTX_free(ctr->ctx_ctr);
622
101
        EVP_CIPHER_CTX_free(ctr->ctx_df);
623
101
        EVP_CIPHER_free(ctr->cipher_ecb);
624
101
        EVP_CIPHER_free(ctr->cipher_ctr);
625
626
101
        OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
627
101
    }
628
101
    ossl_rand_drbg_free(drbg);
629
101
}
630
631
static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
632
20.3k
{
633
20.3k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
634
20.3k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
635
20.3k
    OSSL_PARAM *p;
636
637
20.3k
    p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_USE_DF);
638
20.3k
    if (p != NULL && !OSSL_PARAM_set_int(p, ctr->use_df))
639
0
        return 0;
640
641
20.3k
    p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_CIPHER);
642
20.3k
    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
20.3k
    return ossl_drbg_get_ctx_params(drbg, params);
650
20.3k
}
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
101
{
726
101
    static const OSSL_PARAM known_settable_ctx_params[] = {
727
101
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
728
101
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
729
101
        OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
730
101
        OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
731
        OSSL_PARAM_END
732
101
    };
733
101
    return known_settable_ctx_params;
734
101
}
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
};