Coverage Report

Created: 2026-02-14 07:20

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