Coverage Report

Created: 2025-08-11 07:04

/src/openssl34/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 "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
152k
{
63
152k
    unsigned char *p = &ctr->V[0];
64
152k
    u32 n = 16, c = 1;
65
66
2.43M
    do {
67
2.43M
        --n;
68
2.43M
        c += p[n];
69
2.43M
        p[n] = (u8)c;
70
2.43M
        c >>= 8;
71
2.43M
    } while (n);
72
152k
}
73
74
static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
75
46.1k
{
76
46.1k
    size_t i, n;
77
78
46.1k
    if (in == NULL || inlen == 0)
79
46.0k
        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
115
    n = inlen < ctr->keylen ? inlen : ctr->keylen;
86
115
    if (!ossl_assert(n <= sizeof(ctr->K)))
87
0
        return;
88
3.78k
    for (i = 0; i < n; i++)
89
3.67k
        ctr->K[i] ^= in[i];
90
115
    if (inlen <= ctr->keylen)
91
2
        return;
92
93
113
    n = inlen - ctr->keylen;
94
113
    if (n > 16) {
95
        /* Should never happen */
96
0
        n = 16;
97
0
    }
98
1.92k
    for (i = 0; i < n; i++)
99
1.80k
        ctr->V[i] ^= in[i + ctr->keylen];
100
113
}
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
344
{
108
344
    int i, outlen = AES_BLOCK_SIZE;
109
110
16.8k
    for (i = 0; i < len; i++)
111
16.5k
        out[i] ^= in[i];
112
113
344
    if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
114
344
        || outlen != len)
115
0
        return 0;
116
344
    return 1;
117
344
}
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
269
{
125
269
    unsigned char in_tmp[48];
126
269
    unsigned char num_of_blk = 2;
127
128
269
    memcpy(in_tmp, in, 16);
129
269
    memcpy(in_tmp + 16, in, 16);
130
269
    if (ctr->keylen != 16) {
131
269
        memcpy(in_tmp + 32, in, 16);
132
269
        num_of_blk = 3;
133
269
    }
134
269
    return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
135
269
}
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
75
{
143
75
    unsigned char bltmp[48] = {0};
144
75
    unsigned char num_of_blk;
145
146
75
    memset(ctr->KX, 0, 48);
147
75
    num_of_blk = ctr->keylen == 16 ? 2 : 3;
148
75
    bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
149
75
    bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
150
75
    return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
151
75
}
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
300
{
159
300
    if (in == NULL || inlen == 0)
160
124
        return 1;
161
162
    /* If we have partial block handle it first */
163
176
    if (ctr->bltmp_pos) {
164
142
        size_t left = 16 - ctr->bltmp_pos;
165
166
        /* If we now have a complete block process it */
167
142
        if (inlen >= left) {
168
101
            memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
169
101
            if (!ctr_BCC_blocks(ctr, ctr->bltmp))
170
0
                return 0;
171
101
            ctr->bltmp_pos = 0;
172
101
            inlen -= left;
173
101
            in += left;
174
101
        }
175
142
    }
176
177
    /* Process zero or more complete blocks */
178
269
    for (; inlen >= 16; in += 16, inlen -= 16) {
179
93
        if (!ctr_BCC_blocks(ctr, in))
180
0
            return 0;
181
93
    }
182
183
    /* Copy any remaining partial block to the temporary buffer */
184
176
    if (inlen > 0) {
185
142
        memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
186
142
        ctr->bltmp_pos += inlen;
187
142
    }
188
176
    return 1;
189
176
}
190
191
__owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr)
192
75
{
193
75
    if (ctr->bltmp_pos) {
194
75
        memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
195
75
        if (!ctr_BCC_blocks(ctr, ctr->bltmp))
196
0
            return 0;
197
75
    }
198
75
    return 1;
199
75
}
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
75
{
206
75
    static unsigned char c80 = 0x80;
207
75
    size_t inlen;
208
75
    unsigned char *p = ctr->bltmp;
209
75
    int outlen = AES_BLOCK_SIZE;
210
211
75
    if (!ctr_BCC_init(ctr))
212
0
        return 0;
213
75
    if (in1 == NULL)
214
0
        in1len = 0;
215
75
    if (in2 == NULL)
216
75
        in2len = 0;
217
75
    if (in3 == NULL)
218
49
        in3len = 0;
219
75
    inlen = in1len + in2len + in3len;
220
    /* Initialise L||N in temporary block */
221
75
    *p++ = (inlen >> 24) & 0xff;
222
75
    *p++ = (inlen >> 16) & 0xff;
223
75
    *p++ = (inlen >> 8) & 0xff;
224
75
    *p++ = inlen & 0xff;
225
226
    /* NB keylen is at most 32 bytes */
227
75
    *p++ = 0;
228
75
    *p++ = 0;
229
75
    *p++ = 0;
230
75
    *p = (unsigned char)((ctr->keylen + 16) & 0xff);
231
75
    ctr->bltmp_pos = 8;
232
75
    if (!ctr_BCC_update(ctr, in1, in1len)
233
75
        || !ctr_BCC_update(ctr, in2, in2len)
234
75
        || !ctr_BCC_update(ctr, in3, in3len)
235
75
        || !ctr_BCC_update(ctr, &c80, 1)
236
75
        || !ctr_BCC_final(ctr))
237
0
        return 0;
238
    /* Set up key K */
239
75
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
240
0
        return 0;
241
    /* X follows key K */
242
75
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
243
75
                          AES_BLOCK_SIZE)
244
75
        || outlen != AES_BLOCK_SIZE)
245
0
        return 0;
246
75
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
247
75
                          AES_BLOCK_SIZE)
248
75
        || outlen != AES_BLOCK_SIZE)
249
0
        return 0;
250
75
    if (ctr->keylen != 16)
251
75
        if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
252
75
                              ctr->KX + 16, AES_BLOCK_SIZE)
253
75
            || outlen != AES_BLOCK_SIZE)
254
0
            return 0;
255
75
    return 1;
256
75
}
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
50.7k
{
269
50.7k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
270
50.7k
    int outlen = AES_BLOCK_SIZE;
271
50.7k
    unsigned char V_tmp[48], out[48];
272
50.7k
    unsigned char len;
273
274
    /* correct key is already set up. */
275
50.7k
    memcpy(V_tmp, ctr->V, 16);
276
50.7k
    inc_128(ctr);
277
50.7k
    memcpy(V_tmp + 16, ctr->V, 16);
278
50.7k
    if (ctr->keylen == 16) {
279
0
        len = 32;
280
50.7k
    } else {
281
50.7k
        inc_128(ctr);
282
50.7k
        memcpy(V_tmp + 32, ctr->V, 16);
283
50.7k
        len = 48;
284
50.7k
    }
285
50.7k
    if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
286
50.7k
            || outlen != len)
287
0
        return 0;
288
50.7k
    memcpy(ctr->K, out, ctr->keylen);
289
50.7k
    memcpy(ctr->V, out + ctr->keylen, 16);
290
291
50.7k
    if (ctr->use_df) {
292
        /* If no input reuse existing derived value */
293
27.7k
        if (in1 != NULL || nonce != NULL || in2 != NULL)
294
75
            if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
295
0
                return 0;
296
        /* If this a reuse input in1len != 0 */
297
27.7k
        if (in1len)
298
109
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
299
27.7k
    } else {
300
23.0k
        ctr_XOR(ctr, in1, in1len);
301
23.0k
        ctr_XOR(ctr, in2, in2len);
302
23.0k
    }
303
304
50.7k
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
305
50.7k
        || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
306
0
        return 0;
307
50.7k
    return 1;
308
50.7k
}
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
28
{
315
28
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
316
317
28
    if (entropy == NULL)
318
0
        return 0;
319
320
28
    memset(ctr->K, 0, sizeof(ctr->K));
321
28
    memset(ctr->V, 0, sizeof(ctr->V));
322
28
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
323
0
        return 0;
324
325
28
    inc_128(ctr);
326
28
    if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
327
0
        return 0;
328
28
    return 1;
329
28
}
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
26
{
337
26
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
338
26
    int ret = 0;
339
340
26
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
341
0
        return 0;
342
343
26
    if (!ossl_prov_is_running()
344
26
            || !drbg_ctr_set_ctx_params_locked(drbg, params))
345
0
        goto err;
346
26
    ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
347
26
                                     pstr, pstr_len);
348
26
 err:
349
26
    if (drbg->lock != NULL)
350
0
        CRYPTO_THREAD_unlock(drbg->lock);
351
26
    return ret;
352
26
}
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
17
{
358
17
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
359
360
17
    if (entropy == NULL)
361
0
        return 0;
362
363
17
    inc_128(ctr);
364
17
    if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
365
0
        return 0;
366
17
    return 1;
367
17
}
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
50.6k
{
395
50.6k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
396
50.6k
    unsigned int ctr32, blocks;
397
50.6k
    int outl, buflen;
398
399
50.6k
    if (adin != NULL && adinlen != 0) {
400
34
        inc_128(ctr);
401
402
34
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
403
0
            return 0;
404
        /* This means we reuse derived value */
405
34
        if (ctr->use_df) {
406
34
            adin = NULL;
407
34
            adinlen = 1;
408
34
        }
409
50.6k
    } else {
410
50.6k
        adinlen = 0;
411
50.6k
    }
412
413
50.6k
    inc_128(ctr);
414
415
50.6k
    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
50.6k
    memset(out, 0, outlen);
424
425
50.6k
    do {
426
50.6k
        if (!EVP_CipherInit_ex(ctr->ctx_ctr,
427
50.6k
                               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
50.6k
        buflen = outlen > (1U << 30) ? (1U << 30) : outlen;
438
50.6k
        blocks = (buflen + 15) / 16;
439
440
50.6k
        ctr32 = GETU32(ctr->V + 12) + blocks;
441
50.6k
        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
50.6k
        PUTU32(ctr->V + 12, ctr32);
451
452
50.6k
        if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
453
50.6k
            || outl != buflen)
454
0
            return 0;
455
456
50.6k
        out += buflen;
457
50.6k
        outlen -= buflen;
458
50.6k
    } while (outlen);
459
460
50.6k
    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
461
0
        return 0;
462
50.6k
    return 1;
463
50.6k
}
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
50.6k
{
470
50.6k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
471
472
50.6k
    return ossl_prov_drbg_generate(drbg, out, outlen, strength,
473
50.6k
                                   prediction_resistance, adin, adin_len);
474
50.6k
}
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
146
{
529
146
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
530
146
    int res = 1;
531
532
    /* Maximum number of bits per request = 2^19  = 2^16 bytes */
533
146
    drbg->max_request = 1 << 16;
534
146
    if (ctr->use_df) {
535
144
        drbg->min_entropylen = 0;
536
144
        drbg->max_entropylen = DRBG_MAX_LENGTH;
537
144
        drbg->min_noncelen = 0;
538
144
        drbg->max_noncelen = DRBG_MAX_LENGTH;
539
144
        drbg->max_perslen = DRBG_MAX_LENGTH;
540
144
        drbg->max_adinlen = DRBG_MAX_LENGTH;
541
542
144
        if (ctr->keylen > 0) {
543
26
            drbg->min_entropylen = ctr->keylen;
544
26
            drbg->min_noncelen = drbg->min_entropylen / 2;
545
26
        }
546
144
    } 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
146
    return res;
558
146
}
559
560
static int drbg_ctr_init(PROV_DRBG *drbg)
561
28
{
562
28
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
563
28
    size_t keylen;
564
565
28
    if (ctr->cipher_ctr == NULL) {
566
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
567
0
        return 0;
568
0
    }
569
28
    ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
570
28
    if (ctr->ctx_ecb == NULL)
571
28
        ctr->ctx_ecb = EVP_CIPHER_CTX_new();
572
28
    if (ctr->ctx_ctr == NULL)
573
28
        ctr->ctx_ctr = EVP_CIPHER_CTX_new();
574
28
    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
28
    if (!EVP_CipherInit_ex(ctr->ctx_ecb,
580
28
                           ctr->cipher_ecb, NULL, NULL, NULL, 1)
581
28
        || !EVP_CipherInit_ex(ctr->ctx_ctr,
582
28
                              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
28
    drbg->strength = keylen * 8;
588
28
    drbg->seedlen = keylen + 16;
589
590
28
    if (ctr->use_df) {
591
        /* df initialisation */
592
26
        static const unsigned char df_key[32] = {
593
26
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
594
26
            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
595
26
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
596
26
            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
597
26
        };
598
599
26
        if (ctr->ctx_df == NULL)
600
26
            ctr->ctx_df = EVP_CIPHER_CTX_new();
601
26
        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
26
        if (!EVP_CipherInit_ex(ctr->ctx_df,
607
26
                               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
26
    }
612
28
    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
28
}
620
621
static int drbg_ctr_new(PROV_DRBG *drbg)
622
118
{
623
118
    PROV_DRBG_CTR *ctr;
624
625
118
    ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
626
118
    if (ctr == NULL)
627
0
        return 0;
628
629
118
    ctr->use_df = 1;
630
118
    drbg->data = ctr;
631
118
    OSSL_FIPS_IND_INIT(drbg)
632
118
    return drbg_ctr_init_lengths(drbg);
633
118
}
634
635
static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
636
                                   const OSSL_DISPATCH *parent_dispatch)
637
118
{
638
118
    return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
639
118
                              &drbg_ctr_new, &drbg_ctr_free,
640
118
                              &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
641
118
                              &drbg_ctr_reseed, &drbg_ctr_generate);
642
118
}
643
644
static void drbg_ctr_free(void *vdrbg)
645
117
{
646
117
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
647
117
    PROV_DRBG_CTR *ctr;
648
649
117
    if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
650
117
        EVP_CIPHER_CTX_free(ctr->ctx_ecb);
651
117
        EVP_CIPHER_CTX_free(ctr->ctx_ctr);
652
117
        EVP_CIPHER_CTX_free(ctr->ctx_df);
653
117
        EVP_CIPHER_free(ctr->cipher_ecb);
654
117
        EVP_CIPHER_free(ctr->cipher_ctr);
655
656
117
        OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
657
117
    }
658
117
    ossl_rand_drbg_free(drbg);
659
117
}
660
661
static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
662
79.3k
{
663
79.3k
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
664
79.3k
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
665
79.3k
    OSSL_PARAM *p;
666
79.3k
    int ret = 0, complete = 0;
667
668
79.3k
    if (!ossl_drbg_get_ctx_params_no_lock(drbg, params, &complete))
669
0
        return 0;
670
671
79.3k
    if (complete)
672
79.3k
        return 1;
673
674
48
    if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
675
0
        return 0;
676
677
48
    p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_USE_DF);
678
48
    if (p != NULL && !OSSL_PARAM_set_int(p, ctr->use_df))
679
0
        goto err;
680
681
48
    p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_CIPHER);
682
48
    if (p != NULL) {
683
0
        if (ctr->cipher_ctr == NULL
684
0
            || !OSSL_PARAM_set_utf8_string(p,
685
0
                                           EVP_CIPHER_get0_name(ctr->cipher_ctr)))
686
0
            goto err;
687
0
    }
688
689
48
    ret = ossl_drbg_get_ctx_params(drbg, params);
690
48
 err:
691
48
    if (drbg->lock != NULL)
692
48
        CRYPTO_THREAD_unlock(drbg->lock);
693
694
48
    return ret;
695
48
}
696
697
static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *vctx,
698
                                                      ossl_unused void *provctx)
699
0
{
700
0
    static const OSSL_PARAM known_gettable_ctx_params[] = {
701
0
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
702
0
        OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
703
0
        OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON,
704
0
        OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
705
0
        OSSL_PARAM_END
706
0
    };
707
0
    return known_gettable_ctx_params;
708
0
}
709
710
static int drbg_ctr_set_ctx_params_locked(void *vctx, const OSSL_PARAM params[])
711
31
{
712
31
    PROV_DRBG *ctx = (PROV_DRBG *)vctx;
713
31
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
714
31
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
715
31
    const OSSL_PARAM *p;
716
31
    char *ecb;
717
31
    const char *propquery = NULL;
718
31
    int i, cipher_init = 0;
719
720
31
    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_USE_DF)) != NULL
721
31
            && OSSL_PARAM_get_int(p, &i)) {
722
        /* FIPS errors out in the drbg_ctr_init() call later */
723
31
        ctr->use_df = i != 0;
724
31
        cipher_init = 1;
725
31
    }
726
727
31
    if ((p = OSSL_PARAM_locate_const(params,
728
31
                                     OSSL_DRBG_PARAM_PROPERTIES)) != NULL) {
729
27
        if (p->data_type != OSSL_PARAM_UTF8_STRING)
730
0
            return 0;
731
27
        propquery = (const char *)p->data;
732
27
    }
733
734
31
    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_CIPHER)) != NULL) {
735
31
        const char *base = (const char *)p->data;
736
31
        size_t ctr_str_len = sizeof("CTR") - 1;
737
31
        size_t ecb_str_len = sizeof("ECB") - 1;
738
739
31
        if (p->data_type != OSSL_PARAM_UTF8_STRING
740
31
                || p->data_size < ctr_str_len)
741
5
            return 0;
742
26
        if (OPENSSL_strcasecmp("CTR", base + p->data_size - ctr_str_len) != 0) {
743
22
            ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
744
22
            return 0;
745
22
        }
746
4
        if ((ecb = OPENSSL_strndup(base, p->data_size)) == NULL)
747
0
            return 0;
748
4
        strcpy(ecb + p->data_size - ecb_str_len, "ECB");
749
4
        EVP_CIPHER_free(ctr->cipher_ecb);
750
4
        EVP_CIPHER_free(ctr->cipher_ctr);
751
4
        ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
752
4
        ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
753
4
        OPENSSL_free(ecb);
754
4
        if (ctr->cipher_ctr == NULL || ctr->cipher_ecb == NULL) {
755
0
            ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_FIND_CIPHERS);
756
0
            return 0;
757
0
        }
758
4
        cipher_init = 1;
759
4
    }
760
761
4
    if (cipher_init && !drbg_ctr_init(ctx))
762
0
        return 0;
763
764
4
    return ossl_drbg_set_ctx_params(ctx, params);
765
4
}
766
767
static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[])
768
90
{
769
90
    PROV_DRBG *drbg = (PROV_DRBG *)vctx;
770
90
    int ret;
771
772
90
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
773
0
        return 0;
774
775
90
    ret = drbg_ctr_set_ctx_params_locked(vctx, params);
776
777
90
    if (drbg->lock != NULL)
778
0
        CRYPTO_THREAD_unlock(drbg->lock);
779
780
90
    return ret;
781
90
}
782
783
static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
784
                                                      ossl_unused void *provctx)
785
116
{
786
116
    static const OSSL_PARAM known_settable_ctx_params[] = {
787
116
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
788
116
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
789
116
        OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
790
116
        OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
791
116
        OSSL_PARAM_END
792
116
    };
793
116
    return known_settable_ctx_params;
794
116
}
795
796
const OSSL_DISPATCH ossl_drbg_ctr_functions[] = {
797
    { OSSL_FUNC_RAND_NEWCTX, (void(*)(void))drbg_ctr_new_wrapper },
798
    { OSSL_FUNC_RAND_FREECTX, (void(*)(void))drbg_ctr_free },
799
    { OSSL_FUNC_RAND_INSTANTIATE,
800
      (void(*)(void))drbg_ctr_instantiate_wrapper },
801
    { OSSL_FUNC_RAND_UNINSTANTIATE,
802
      (void(*)(void))drbg_ctr_uninstantiate_wrapper },
803
    { OSSL_FUNC_RAND_GENERATE, (void(*)(void))drbg_ctr_generate_wrapper },
804
    { OSSL_FUNC_RAND_RESEED, (void(*)(void))drbg_ctr_reseed_wrapper },
805
    { OSSL_FUNC_RAND_ENABLE_LOCKING, (void(*)(void))ossl_drbg_enable_locking },
806
    { OSSL_FUNC_RAND_LOCK, (void(*)(void))ossl_drbg_lock },
807
    { OSSL_FUNC_RAND_UNLOCK, (void(*)(void))ossl_drbg_unlock },
808
    { OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS,
809
      (void(*)(void))drbg_ctr_settable_ctx_params },
810
    { OSSL_FUNC_RAND_SET_CTX_PARAMS, (void(*)(void))drbg_ctr_set_ctx_params },
811
    { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
812
      (void(*)(void))drbg_ctr_gettable_ctx_params },
813
    { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))drbg_ctr_get_ctx_params },
814
    { OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
815
      (void(*)(void))drbg_ctr_verify_zeroization },
816
    { OSSL_FUNC_RAND_GET_SEED, (void(*)(void))ossl_drbg_get_seed },
817
    { OSSL_FUNC_RAND_CLEAR_SEED, (void(*)(void))ossl_drbg_clear_seed },
818
    OSSL_DISPATCH_END
819
};