Coverage Report

Created: 2025-08-28 07:07

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