Coverage Report

Created: 2025-08-28 07:07

/src/openssl35/providers/implementations/rands/drbg_ctr.c
Line
Count
Source (jump to first uncovered line)
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
238k
{
66
238k
    unsigned char *p = &ctr->V[0];
67
238k
    u32 n = 16, c = 1;
68
69
3.82M
    do {
70
3.82M
        --n;
71
3.82M
        c += p[n];
72
3.82M
        p[n] = (u8)c;
73
3.82M
        c >>= 8;
74
3.82M
    } while (n);
75
238k
}
76
77
static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
78
53.8k
{
79
53.8k
    size_t i, n;
80
81
53.8k
    if (in == NULL || inlen == 0)
82
53.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
122
    n = inlen < ctr->keylen ? inlen : ctr->keylen;
89
122
    if (!ossl_assert(n <= sizeof(ctr->K)))
90
0
        return;
91
4.02k
    for (i = 0; i < n; i++)
92
3.89k
        ctr->K[i] ^= in[i];
93
122
    if (inlen <= ctr->keylen)
94
2
        return;
95
96
120
    n = inlen - ctr->keylen;
97
120
    if (n > 16) {
98
        /* Should never happen */
99
0
        n = 16;
100
0
    }
101
2.04k
    for (i = 0; i < n; i++)
102
1.92k
        ctr->V[i] ^= in[i + ctr->keylen];
103
120
}
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
368
{
111
368
    int i, outlen = AES_BLOCK_SIZE;
112
113
18.0k
    for (i = 0; i < len; i++)
114
17.6k
        out[i] ^= in[i];
115
116
368
    if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
117
368
        || outlen != len)
118
0
        return 0;
119
368
    return 1;
120
368
}
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
288
{
128
288
    unsigned char in_tmp[48];
129
288
    unsigned char num_of_blk = 2;
130
131
288
    memcpy(in_tmp, in, 16);
132
288
    memcpy(in_tmp + 16, in, 16);
133
288
    if (ctr->keylen != 16) {
134
288
        memcpy(in_tmp + 32, in, 16);
135
288
        num_of_blk = 3;
136
288
    }
137
288
    return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
138
288
}
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
80
{
146
80
    unsigned char bltmp[48] = {0};
147
80
    unsigned char num_of_blk;
148
149
80
    memset(ctr->KX, 0, 48);
150
80
    num_of_blk = ctr->keylen == 16 ? 2 : 3;
151
80
    bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
152
80
    bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
153
80
    return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
154
80
}
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
320
{
162
320
    if (in == NULL || inlen == 0)
163
132
        return 1;
164
165
    /* If we have partial block handle it first */
166
188
    if (ctr->bltmp_pos) {
167
152
        size_t left = 16 - ctr->bltmp_pos;
168
169
        /* If we now have a complete block process it */
170
152
        if (inlen >= left) {
171
108
            memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
172
108
            if (!ctr_BCC_blocks(ctr, ctr->bltmp))
173
0
                return 0;
174
108
            ctr->bltmp_pos = 0;
175
108
            inlen -= left;
176
108
            in += left;
177
108
        }
178
152
    }
179
180
    /* Process zero or more complete blocks */
181
288
    for (; inlen >= 16; in += 16, inlen -= 16) {
182
100
        if (!ctr_BCC_blocks(ctr, in))
183
0
            return 0;
184
100
    }
185
186
    /* Copy any remaining partial block to the temporary buffer */
187
188
    if (inlen > 0) {
188
152
        memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
189
152
        ctr->bltmp_pos += inlen;
190
152
    }
191
188
    return 1;
192
188
}
193
194
__owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr)
195
80
{
196
80
    if (ctr->bltmp_pos) {
197
80
        memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
198
80
        if (!ctr_BCC_blocks(ctr, ctr->bltmp))
199
0
            return 0;
200
80
    }
201
80
    return 1;
202
80
}
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
80
{
209
80
    static unsigned char c80 = 0x80;
210
80
    size_t inlen;
211
80
    unsigned char *p = ctr->bltmp;
212
80
    int outlen = AES_BLOCK_SIZE;
213
214
80
    if (!ctr_BCC_init(ctr))
215
0
        return 0;
216
80
    if (in1 == NULL)
217
0
        in1len = 0;
218
80
    if (in2 == NULL)
219
80
        in2len = 0;
220
80
    if (in3 == NULL)
221
52
        in3len = 0;
222
80
    inlen = in1len + in2len + in3len;
223
    /* Initialise L||N in temporary block */
224
80
    *p++ = (inlen >> 24) & 0xff;
225
80
    *p++ = (inlen >> 16) & 0xff;
226
80
    *p++ = (inlen >> 8) & 0xff;
227
80
    *p++ = inlen & 0xff;
228
229
    /* NB keylen is at most 32 bytes */
230
80
    *p++ = 0;
231
80
    *p++ = 0;
232
80
    *p++ = 0;
233
80
    *p = (unsigned char)((ctr->keylen + 16) & 0xff);
234
80
    ctr->bltmp_pos = 8;
235
80
    if (!ctr_BCC_update(ctr, in1, in1len)
236
80
        || !ctr_BCC_update(ctr, in2, in2len)
237
80
        || !ctr_BCC_update(ctr, in3, in3len)
238
80
        || !ctr_BCC_update(ctr, &c80, 1)
239
80
        || !ctr_BCC_final(ctr))
240
0
        return 0;
241
    /* Set up key K */
242
80
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
243
0
        return 0;
244
    /* X follows key K */
245
80
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
246
80
                          AES_BLOCK_SIZE)
247
80
        || outlen != AES_BLOCK_SIZE)
248
0
        return 0;
249
80
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
250
80
                          AES_BLOCK_SIZE)
251
80
        || outlen != AES_BLOCK_SIZE)
252
0
        return 0;
253
80
    if (ctr->keylen != 16)
254
80
        if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
255
80
                              ctr->KX + 16, AES_BLOCK_SIZE)
256
80
            || outlen != AES_BLOCK_SIZE)
257
0
            return 0;
258
80
    return 1;
259
80
}
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
79.6k
{
272
79.6k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
273
79.6k
    int outlen = AES_BLOCK_SIZE;
274
79.6k
    unsigned char V_tmp[48], out[48];
275
79.6k
    unsigned char len;
276
277
    /* correct key is already set up. */
278
79.6k
    memcpy(V_tmp, ctr->V, 16);
279
79.6k
    inc_128(ctr);
280
79.6k
    memcpy(V_tmp + 16, ctr->V, 16);
281
79.6k
    if (ctr->keylen == 16) {
282
0
        len = 32;
283
79.6k
    } else {
284
79.6k
        inc_128(ctr);
285
79.6k
        memcpy(V_tmp + 32, ctr->V, 16);
286
79.6k
        len = 48;
287
79.6k
    }
288
79.6k
    if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
289
79.6k
            || outlen != len)
290
0
        return 0;
291
79.6k
    memcpy(ctr->K, out, ctr->keylen);
292
79.6k
    memcpy(ctr->V, out + ctr->keylen, 16);
293
294
79.6k
    if (ctr->use_df) {
295
        /* If no input reuse existing derived value */
296
52.7k
        if (in1 != NULL || nonce != NULL || in2 != NULL)
297
80
            if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
298
0
                return 0;
299
        /* If this a reuse input in1len != 0 */
300
52.7k
        if (in1len)
301
116
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
302
52.7k
    } else {
303
26.8k
        ctr_XOR(ctr, in1, in1len);
304
26.8k
        ctr_XOR(ctr, in2, in2len);
305
26.8k
    }
306
307
79.6k
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
308
79.6k
        || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
309
0
        return 0;
310
79.6k
    return 1;
311
79.6k
}
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
30
{
318
30
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
319
320
30
    if (entropy == NULL)
321
0
        return 0;
322
323
30
    memset(ctr->K, 0, sizeof(ctr->K));
324
30
    memset(ctr->V, 0, sizeof(ctr->V));
325
30
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
326
0
        return 0;
327
328
30
    inc_128(ctr);
329
30
    if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
330
0
        return 0;
331
30
    return 1;
332
30
}
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
15
{
340
15
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
341
15
    int ret = 0;
342
343
15
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
344
0
        return 0;
345
346
15
    if (!ossl_prov_is_running()
347
15
            || !drbg_ctr_set_ctx_params_locked(drbg, params))
348
0
        goto err;
349
15
    ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
350
15
                                     pstr, pstr_len);
351
15
 err:
352
15
    if (drbg->lock != NULL)
353
0
        CRYPTO_THREAD_unlock(drbg->lock);
354
15
    return ret;
355
15
}
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
18
{
361
18
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
362
363
18
    if (entropy == NULL)
364
0
        return 0;
365
366
18
    inc_128(ctr);
367
18
    if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
368
0
        return 0;
369
18
    return 1;
370
18
}
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
79.5k
{
398
79.5k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
399
79.5k
    unsigned int ctr32, blocks;
400
79.5k
    int outl, buflen;
401
402
79.5k
    if (adin != NULL && adinlen != 0) {
403
36
        inc_128(ctr);
404
405
36
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
406
0
            return 0;
407
        /* This means we reuse derived value */
408
36
        if (ctr->use_df) {
409
36
            adin = NULL;
410
36
            adinlen = 1;
411
36
        }
412
79.5k
    } else {
413
79.5k
        adinlen = 0;
414
79.5k
    }
415
416
79.5k
    inc_128(ctr);
417
418
79.5k
    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
79.5k
    memset(out, 0, outlen);
427
428
79.5k
    do {
429
79.5k
        if (!EVP_CipherInit_ex(ctr->ctx_ctr,
430
79.5k
                               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
79.5k
        buflen = outlen > (1U << 30) ? (1U << 30) : outlen;
441
79.5k
        blocks = (buflen + 15) / 16;
442
443
79.5k
        ctr32 = GETU32(ctr->V + 12) + blocks;
444
79.5k
        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
79.5k
        PUTU32(ctr->V + 12, ctr32);
454
455
79.5k
        if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
456
79.5k
            || outl != buflen)
457
0
            return 0;
458
459
79.5k
        out += buflen;
460
79.5k
        outlen -= buflen;
461
79.5k
    } while (outlen);
462
463
79.5k
    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
464
0
        return 0;
465
79.5k
    return 1;
466
79.5k
}
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
79.5k
{
473
79.5k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
474
475
79.5k
    return ossl_prov_drbg_generate(drbg, out, outlen, strength,
476
79.5k
                                   prediction_resistance, adin, adin_len);
477
79.5k
}
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
145
{
532
145
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
533
145
    int res = 1;
534
535
    /* Maximum number of bits per request = 2^19  = 2^16 bytes */
536
145
    drbg->max_request = 1 << 16;
537
145
    if (ctr->use_df) {
538
143
        drbg->min_entropylen = 0;
539
143
        drbg->max_entropylen = DRBG_MAX_LENGTH;
540
143
        drbg->min_noncelen = 0;
541
143
        drbg->max_noncelen = DRBG_MAX_LENGTH;
542
143
        drbg->max_perslen = DRBG_MAX_LENGTH;
543
143
        drbg->max_adinlen = DRBG_MAX_LENGTH;
544
545
143
        if (ctr->keylen > 0) {
546
28
            drbg->min_entropylen = ctr->keylen;
547
28
            drbg->min_noncelen = drbg->min_entropylen / 2;
548
28
        }
549
143
    } 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
145
    return res;
561
145
}
562
563
static int drbg_ctr_init(PROV_DRBG *drbg)
564
30
{
565
30
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
566
30
    size_t keylen;
567
568
30
    if (ctr->cipher_ctr == NULL) {
569
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
570
0
        return 0;
571
0
    }
572
30
    ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
573
30
    if (ctr->ctx_ecb == NULL)
574
30
        ctr->ctx_ecb = EVP_CIPHER_CTX_new();
575
30
    if (ctr->ctx_ctr == NULL)
576
30
        ctr->ctx_ctr = EVP_CIPHER_CTX_new();
577
30
    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
30
    if (!EVP_CipherInit_ex(ctr->ctx_ecb,
583
30
                           ctr->cipher_ecb, NULL, NULL, NULL, 1)
584
30
        || !EVP_CipherInit_ex(ctr->ctx_ctr,
585
30
                              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
30
    drbg->strength = keylen * 8;
591
30
    drbg->seedlen = keylen + 16;
592
593
30
    if (ctr->use_df) {
594
        /* df initialisation */
595
28
        static const unsigned char df_key[32] = {
596
28
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
597
28
            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
598
28
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
599
28
            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
600
28
        };
601
602
28
        if (ctr->ctx_df == NULL)
603
28
            ctr->ctx_df = EVP_CIPHER_CTX_new();
604
28
        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
28
        if (!EVP_CipherInit_ex(ctr->ctx_df,
610
28
                               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
28
    }
615
30
    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
30
}
623
624
static int drbg_ctr_new(PROV_DRBG *drbg)
625
115
{
626
115
    PROV_DRBG_CTR *ctr;
627
628
115
    ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
629
115
    if (ctr == NULL)
630
0
        return 0;
631
632
115
    ctr->use_df = 1;
633
115
    drbg->data = ctr;
634
115
    OSSL_FIPS_IND_INIT(drbg)
635
115
    return drbg_ctr_init_lengths(drbg);
636
115
}
637
638
static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
639
                                   const OSSL_DISPATCH *parent_dispatch)
640
115
{
641
115
    return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
642
115
                              &drbg_ctr_new, &drbg_ctr_free,
643
115
                              &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
644
115
                              &drbg_ctr_reseed, &drbg_ctr_generate);
645
115
}
646
647
static void drbg_ctr_free(void *vdrbg)
648
114
{
649
114
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
650
114
    PROV_DRBG_CTR *ctr;
651
652
114
    if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
653
114
        EVP_CIPHER_CTX_free(ctr->ctx_ecb);
654
114
        EVP_CIPHER_CTX_free(ctr->ctx_ctr);
655
114
        EVP_CIPHER_CTX_free(ctr->ctx_df);
656
114
        EVP_CIPHER_free(ctr->cipher_ecb);
657
114
        EVP_CIPHER_free(ctr->cipher_ctr);
658
659
114
        OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
660
114
    }
661
114
    ossl_rand_drbg_free(drbg);
662
114
}
663
664
static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
665
88.5k
{
666
88.5k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
667
88.5k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
668
88.5k
    OSSL_PARAM *p;
669
88.5k
    int ret = 0, complete = 0;
670
671
88.5k
    if (!ossl_drbg_get_ctx_params_no_lock(drbg, params, &complete))
672
0
        return 0;
673
674
88.5k
    if (complete)
675
88.4k
        return 1;
676
677
27
    if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
678
0
        return 0;
679
680
27
    p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_USE_DF);
681
27
    if (p != NULL && !OSSL_PARAM_set_int(p, ctr->use_df))
682
0
        goto err;
683
684
27
    p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_CIPHER);
685
27
    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
27
    ret = ossl_drbg_get_ctx_params(drbg, params);
693
27
 err:
694
27
    if (drbg->lock != NULL)
695
27
        CRYPTO_THREAD_unlock(drbg->lock);
696
697
27
    return ret;
698
27
}
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
83
{
715
83
    PROV_DRBG *ctx = (PROV_DRBG *)vctx;
716
83
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
717
83
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
718
83
    OSSL_PROVIDER *prov = NULL;
719
83
    const OSSL_PARAM *p;
720
83
    char *ecb;
721
83
    const char *propquery = NULL;
722
83
    int i, cipher_init = 0;
723
724
83
    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_USE_DF)) != NULL
725
83
            && OSSL_PARAM_get_int(p, &i)) {
726
        /* FIPS errors out in the drbg_ctr_init() call later */
727
83
        ctr->use_df = i != 0;
728
83
        cipher_init = 1;
729
83
    }
730
731
83
    if ((p = OSSL_PARAM_locate_const(params,
732
83
                                     OSSL_DRBG_PARAM_PROPERTIES)) != NULL) {
733
59
        if (p->data_type != OSSL_PARAM_UTF8_STRING)
734
0
            return 0;
735
59
        propquery = (const char *)p->data;
736
59
    }
737
738
83
    if ((p = OSSL_PARAM_locate_const(params,
739
83
                                     OSSL_PROV_PARAM_CORE_PROV_NAME)) != NULL) {
740
44
        if (p->data_type != OSSL_PARAM_UTF8_STRING)
741
0
            return 0;
742
44
        if ((prov = ossl_provider_find(libctx,
743
44
                                       (const char *)p->data, 1)) == NULL)
744
18
            return 0;
745
44
    }
746
747
65
    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_CIPHER)) != NULL) {
748
65
        const char *base = (const char *)p->data;
749
65
        size_t ctr_str_len = sizeof("CTR") - 1;
750
65
        size_t ecb_str_len = sizeof("ECB") - 1;
751
752
65
        if (p->data_type != OSSL_PARAM_UTF8_STRING
753
65
                || p->data_size < ctr_str_len) {
754
20
            ossl_provider_free(prov);
755
20
            return 0;
756
20
        }
757
45
        if (OPENSSL_strcasecmp("CTR", base + p->data_size - ctr_str_len) != 0) {
758
21
            ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
759
21
            ossl_provider_free(prov);
760
21
            return 0;
761
21
        }
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
65
{
807
65
    PROV_DRBG *drbg = (PROV_DRBG *)vctx;
808
65
    int ret;
809
810
65
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
811
0
        return 0;
812
813
65
    ret = drbg_ctr_set_ctx_params_locked(vctx, params);
814
815
65
    if (drbg->lock != NULL)
816
0
        CRYPTO_THREAD_unlock(drbg->lock);
817
818
65
    return ret;
819
65
}
820
821
static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
822
                                                      ossl_unused void *provctx)
823
113
{
824
113
    static const OSSL_PARAM known_settable_ctx_params[] = {
825
113
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
826
113
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
827
113
        OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
828
113
        OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
829
113
        OSSL_PARAM_END
830
113
    };
831
113
    return known_settable_ctx_params;
832
113
}
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
};