Coverage Report

Created: 2026-07-16 07:11

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