Coverage Report

Created: 2025-11-16 06:40

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