Coverage Report

Created: 2025-11-16 06:40

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