Coverage Report

Created: 2025-12-31 06:58

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