Coverage Report

Created: 2026-02-22 06: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-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 "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
0
{
73
0
    unsigned char *p = &ctr->V[0];
74
0
    u32 n = 16, c = 1;
75
76
0
    do {
77
0
        --n;
78
0
        c += p[n];
79
0
        p[n] = (u8)c;
80
0
        c >>= 8;
81
0
    } while (n);
82
0
}
83
84
static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
85
0
{
86
0
    size_t i, n;
87
88
0
    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
0
    n = inlen < ctr->keylen ? inlen : ctr->keylen;
96
0
    if (!ossl_assert(n <= sizeof(ctr->K)))
97
0
        return;
98
0
    for (i = 0; i < n; i++)
99
0
        ctr->K[i] ^= in[i];
100
0
    if (inlen <= ctr->keylen)
101
0
        return;
102
103
0
    n = inlen - ctr->keylen;
104
0
    if (n > 16) {
105
        /* Should never happen */
106
0
        n = 16;
107
0
    }
108
0
    for (i = 0; i < n; i++)
109
0
        ctr->V[i] ^= in[i + ctr->keylen];
110
0
}
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
0
{
118
0
    int i, outlen = AES_BLOCK_SIZE;
119
120
0
    for (i = 0; i < len; i++)
121
0
        out[i] ^= in[i];
122
123
0
    if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
124
0
        || outlen != len)
125
0
        return 0;
126
0
    return 1;
127
0
}
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
0
{
134
0
    unsigned char in_tmp[48];
135
0
    unsigned char num_of_blk = 2;
136
137
0
    memcpy(in_tmp, in, 16);
138
0
    memcpy(in_tmp + 16, in, 16);
139
0
    if (ctr->keylen != 16) {
140
0
        memcpy(in_tmp + 32, in, 16);
141
0
        num_of_blk = 3;
142
0
    }
143
0
    return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
144
0
}
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
0
{
152
0
    unsigned char bltmp[48] = { 0 };
153
0
    unsigned char num_of_blk;
154
155
0
    memset(ctr->KX, 0, 48);
156
0
    num_of_blk = ctr->keylen == 16 ? 2 : 3;
157
0
    bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
158
0
    bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
159
0
    return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
160
0
}
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
0
{
168
0
    if (in == NULL || inlen == 0)
169
0
        return 1;
170
171
    /* If we have partial block handle it first */
172
0
    if (ctr->bltmp_pos) {
173
0
        size_t left = 16 - ctr->bltmp_pos;
174
175
        /* If we now have a complete block process it */
176
0
        if (inlen >= left) {
177
0
            memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
178
0
            if (!ctr_BCC_blocks(ctr, ctr->bltmp))
179
0
                return 0;
180
0
            ctr->bltmp_pos = 0;
181
0
            inlen -= left;
182
0
            in += left;
183
0
        }
184
0
    }
185
186
    /* Process zero or more complete blocks */
187
0
    for (; inlen >= 16; in += 16, inlen -= 16) {
188
0
        if (!ctr_BCC_blocks(ctr, in))
189
0
            return 0;
190
0
    }
191
192
    /* Copy any remaining partial block to the temporary buffer */
193
0
    if (inlen > 0) {
194
0
        memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
195
0
        ctr->bltmp_pos += inlen;
196
0
    }
197
0
    return 1;
198
0
}
199
200
__owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr)
201
0
{
202
0
    if (ctr->bltmp_pos) {
203
0
        memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
204
0
        if (!ctr_BCC_blocks(ctr, ctr->bltmp))
205
0
            return 0;
206
0
    }
207
0
    return 1;
208
0
}
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
0
{
215
0
    static unsigned char c80 = 0x80;
216
0
    size_t inlen;
217
0
    unsigned char *p = ctr->bltmp;
218
0
    int outlen = AES_BLOCK_SIZE;
219
220
0
    if (!ctr_BCC_init(ctr))
221
0
        return 0;
222
0
    if (in1 == NULL)
223
0
        in1len = 0;
224
0
    if (in2 == NULL)
225
0
        in2len = 0;
226
0
    if (in3 == NULL)
227
0
        in3len = 0;
228
0
    inlen = in1len + in2len + in3len;
229
    /* Initialise L||N in temporary block */
230
0
    *p++ = (inlen >> 24) & 0xff;
231
0
    *p++ = (inlen >> 16) & 0xff;
232
0
    *p++ = (inlen >> 8) & 0xff;
233
0
    *p++ = inlen & 0xff;
234
235
    /* NB keylen is at most 32 bytes */
236
0
    *p++ = 0;
237
0
    *p++ = 0;
238
0
    *p++ = 0;
239
0
    *p = (unsigned char)((ctr->keylen + 16) & 0xff);
240
0
    ctr->bltmp_pos = 8;
241
0
    if (!ctr_BCC_update(ctr, in1, in1len)
242
0
        || !ctr_BCC_update(ctr, in2, in2len)
243
0
        || !ctr_BCC_update(ctr, in3, in3len)
244
0
        || !ctr_BCC_update(ctr, &c80, 1)
245
0
        || !ctr_BCC_final(ctr))
246
0
        return 0;
247
    /* Set up key K */
248
0
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
249
0
        return 0;
250
    /* X follows key K */
251
0
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
252
0
            AES_BLOCK_SIZE)
253
0
        || outlen != AES_BLOCK_SIZE)
254
0
        return 0;
255
0
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
256
0
            AES_BLOCK_SIZE)
257
0
        || outlen != AES_BLOCK_SIZE)
258
0
        return 0;
259
0
    if (ctr->keylen != 16)
260
0
        if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
261
0
                ctr->KX + 16, AES_BLOCK_SIZE)
262
0
            || outlen != AES_BLOCK_SIZE)
263
0
            return 0;
264
0
    return 1;
265
0
}
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
0
{
278
0
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
279
0
    int outlen = AES_BLOCK_SIZE;
280
0
    unsigned char V_tmp[48], out[48];
281
0
    unsigned char len;
282
283
    /* correct key is already set up. */
284
0
    memcpy(V_tmp, ctr->V, 16);
285
0
    inc_128(ctr);
286
0
    memcpy(V_tmp + 16, ctr->V, 16);
287
0
    if (ctr->keylen == 16) {
288
0
        len = 32;
289
0
    } else {
290
0
        inc_128(ctr);
291
0
        memcpy(V_tmp + 32, ctr->V, 16);
292
0
        len = 48;
293
0
    }
294
0
    if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
295
0
        || outlen != len)
296
0
        return 0;
297
0
    memcpy(ctr->K, out, ctr->keylen);
298
0
    memcpy(ctr->V, out + ctr->keylen, 16);
299
300
0
    if (ctr->use_df) {
301
        /* If no input reuse existing derived value */
302
0
        if (in1 != NULL || nonce != NULL || in2 != NULL)
303
0
            if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
304
0
                return 0;
305
        /* If this a reuse input in1len != 0 */
306
0
        if (in1len)
307
0
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
308
0
    } else {
309
0
        ctr_XOR(ctr, in1, in1len);
310
0
        ctr_XOR(ctr, in2, in2len);
311
0
    }
312
313
0
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
314
0
        || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
315
0
        return 0;
316
0
    return 1;
317
0
}
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
0
{
324
0
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
325
326
0
    if (entropy == NULL)
327
0
        return 0;
328
329
0
    memset(ctr->K, 0, sizeof(ctr->K));
330
0
    memset(ctr->V, 0, sizeof(ctr->V));
331
0
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
332
0
        return 0;
333
334
0
    inc_128(ctr);
335
0
    if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
336
0
        return 0;
337
0
    return 1;
338
0
}
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
0
{
346
0
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
347
0
    struct drbg_set_ctx_params_st p;
348
0
    int ret = 0;
349
350
0
    if (drbg == NULL || !drbg_ctr_set_ctx_params_decoder(params, &p))
351
0
        return 0;
352
353
0
    if (drbg->lock != NULL && !CRYPTO_THREAD_write_lock(drbg->lock))
354
0
        return 0;
355
356
0
    if (!ossl_prov_is_running()
357
0
        || !drbg_ctr_set_ctx_params_locked(drbg, &p))
358
0
        goto err;
359
0
    ret = ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
360
0
        pstr, pstr_len);
361
0
err:
362
0
    if (drbg->lock != NULL)
363
0
        CRYPTO_THREAD_unlock(drbg->lock);
364
0
    return ret;
365
0
}
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
0
{
371
0
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
372
373
0
    if (entropy == NULL)
374
0
        return 0;
375
376
0
    inc_128(ctr);
377
0
    if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
378
0
        return 0;
379
0
    return 1;
380
0
}
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
0
{
386
0
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
387
388
0
    return ossl_prov_drbg_reseed(drbg, prediction_resistance, ent, ent_len,
389
0
        adin, adin_len);
390
0
}
391
392
static void ctr96_inc(unsigned char *counter)
393
0
{
394
0
    u32 n = 12, c = 1;
395
396
0
    do {
397
0
        --n;
398
0
        c += counter[n];
399
0
        counter[n] = (u8)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
0
{
408
0
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
409
0
    unsigned int ctr32, blocks;
410
0
    int outl, buflen;
411
412
0
    if (adin != NULL && adinlen != 0) {
413
0
        inc_128(ctr);
414
415
0
        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
416
0
            return 0;
417
        /* This means we reuse derived value */
418
0
        if (ctr->use_df) {
419
0
            adin = NULL;
420
0
            adinlen = 1;
421
0
        }
422
0
    } else {
423
0
        adinlen = 0;
424
0
    }
425
426
0
    inc_128(ctr);
427
428
0
    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
0
    memset(out, 0, outlen);
437
438
0
    do {
439
0
        if (!EVP_CipherInit_ex(ctr->ctx_ctr,
440
0
                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
0
        buflen = outlen > (1U << 30) ? (1 << 30) : (int)outlen;
451
0
        blocks = (buflen + 15) / 16;
452
453
0
        ctr32 = GETU32(ctr->V + 12) + blocks;
454
0
        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
0
        PUTU32(ctr->V + 12, ctr32);
464
465
0
        if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
466
0
            || outl != buflen)
467
0
            return 0;
468
469
0
        out += buflen;
470
0
        outlen -= buflen;
471
0
    } while (outlen);
472
473
0
    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
474
0
        return 0;
475
0
    return 1;
476
0
}
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
0
{
482
0
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
483
484
0
    return ossl_prov_drbg_generate(drbg, out, outlen, strength,
485
0
        prediction_resistance, adin, adin_len);
486
0
}
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
0
{
541
0
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
542
0
    int res = 1;
543
544
    /* Maximum number of bits per request = 2^19  = 2^16 bytes */
545
0
    drbg->max_request = 1 << 16;
546
0
    if (ctr->use_df) {
547
0
        drbg->min_entropylen = 0;
548
0
        drbg->max_entropylen = DRBG_MAX_LENGTH;
549
0
        drbg->min_noncelen = 0;
550
0
        drbg->max_noncelen = DRBG_MAX_LENGTH;
551
0
        drbg->max_perslen = DRBG_MAX_LENGTH;
552
0
        drbg->max_adinlen = DRBG_MAX_LENGTH;
553
554
0
        if (ctr->keylen > 0) {
555
0
            drbg->min_entropylen = ctr->keylen;
556
0
            drbg->min_noncelen = drbg->min_entropylen / 2;
557
0
        }
558
0
    } 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
0
    return res;
570
0
}
571
572
static int drbg_ctr_init(PROV_DRBG *drbg)
573
0
{
574
0
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
575
0
    size_t keylen;
576
577
0
    if (ctr->cipher_ctr == NULL) {
578
0
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
579
0
        return 0;
580
0
    }
581
0
    ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
582
0
    if (ctr->ctx_ecb == NULL)
583
0
        ctr->ctx_ecb = EVP_CIPHER_CTX_new();
584
0
    if (ctr->ctx_ctr == NULL)
585
0
        ctr->ctx_ctr = EVP_CIPHER_CTX_new();
586
0
    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
0
    if (!EVP_CipherInit_ex(ctr->ctx_ecb,
592
0
            ctr->cipher_ecb, NULL, NULL, NULL, 1)
593
0
        || !EVP_CipherInit_ex(ctr->ctx_ctr,
594
0
            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
0
    drbg->strength = (unsigned int)(keylen * 8);
600
0
    drbg->seedlen = keylen + 16;
601
602
0
    if (ctr->use_df) {
603
        /* df initialisation */
604
0
        static const unsigned char df_key[32] = {
605
0
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
606
0
            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
607
0
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
608
0
            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
609
0
        };
610
611
0
        if (ctr->ctx_df == NULL)
612
0
            ctr->ctx_df = EVP_CIPHER_CTX_new();
613
0
        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
0
        if (!EVP_CipherInit_ex(ctr->ctx_df,
619
0
                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
0
    }
624
0
    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
0
}
632
633
static int drbg_ctr_new(PROV_DRBG *drbg)
634
0
{
635
0
    PROV_DRBG_CTR *ctr;
636
637
0
    ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
638
0
    if (ctr == NULL)
639
0
        return 0;
640
641
0
    ctr->use_df = 1;
642
0
    drbg->data = ctr;
643
0
    OSSL_FIPS_IND_INIT(drbg)
644
0
    return drbg_ctr_init_lengths(drbg);
645
0
}
646
647
static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
648
    const OSSL_DISPATCH *parent_dispatch)
649
0
{
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
0
    return ossl_rand_drbg_new(provctx, parent, parent_dispatch,
657
0
        &drbg_ctr_new, &drbg_ctr_free,
658
0
        &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
659
0
        &drbg_ctr_reseed, &drbg_ctr_generate);
660
0
}
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
0
{
681
0
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
682
0
    PROV_DRBG_CTR *ctr;
683
0
    struct drbg_ctr_get_ctx_params_st p;
684
0
    int ret = 0, complete = 0;
685
686
0
    if (drbg == NULL || !drbg_ctr_get_ctx_params_decoder(params, &p))
687
0
        return 0;
688
689
0
    if (!ossl_drbg_get_ctx_params_no_lock(drbg, &p, params, &complete))
690
0
        return 0;
691
692
0
    if (complete)
693
0
        return 1;
694
695
0
    ctr = (PROV_DRBG_CTR *)drbg->data;
696
697
0
    if (drbg->lock != NULL && !CRYPTO_THREAD_read_lock(drbg->lock))
698
0
        return 0;
699
700
0
    if (p.df != NULL && !OSSL_PARAM_set_int(p.df, ctr->use_df))
701
0
        goto err;
702
703
0
    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
0
    ret = ossl_drbg_get_ctx_params(drbg, &p);
711
0
err:
712
0
    if (drbg->lock != NULL)
713
0
        CRYPTO_THREAD_unlock(drbg->lock);
714
715
0
    return ret;
716
0
}
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
0
{
727
0
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
728
0
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
729
0
    OSSL_PROVIDER *prov = NULL;
730
0
    char *ecb;
731
0
    const char *propquery = NULL;
732
0
    int i, cipher_init = 0;
733
734
0
    if (p->df != NULL && OSSL_PARAM_get_int(p->df, &i)) {
735
        /* FIPS errors out in the drbg_ctr_init() call later */
736
0
        ctr->use_df = i != 0;
737
0
        cipher_init = 1;
738
0
    }
739
740
0
    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
0
    if (p->prov != NULL) {
747
0
        if (p->prov->data_type != OSSL_PARAM_UTF8_STRING)
748
0
            return 0;
749
0
        if ((prov = ossl_provider_find(libctx,
750
0
                 (const char *)p->prov->data, 1))
751
0
            == NULL)
752
0
            return 0;
753
0
    }
754
755
0
    if (p->cipher != NULL) {
756
0
        const char *base = (const char *)p->cipher->data;
757
0
        size_t ctr_str_len = sizeof("CTR") - 1;
758
0
        size_t ecb_str_len = sizeof("ECB") - 1;
759
760
0
        if (p->cipher->data_type != OSSL_PARAM_UTF8_STRING
761
0
            || p->cipher->data_size < ctr_str_len) {
762
0
            ossl_provider_free(prov);
763
0
            return 0;
764
0
        }
765
0
        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
0
        if ((ecb = OPENSSL_strndup(base, p->cipher->data_size)) == NULL) {
771
0
            ossl_provider_free(prov);
772
0
            return 0;
773
0
        }
774
0
        strcpy(ecb + p->cipher->data_size - ecb_str_len, "ECB");
775
0
        EVP_CIPHER_free(ctr->cipher_ecb);
776
0
        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
0
        (void)ERR_set_mark();
782
0
        ctr->cipher_ctr = evp_cipher_fetch_from_prov(prov, base, NULL);
783
0
        if (ctr->cipher_ctr == NULL) {
784
0
            (void)ERR_pop_to_mark();
785
0
            ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
786
0
        } else {
787
0
            (void)ERR_clear_last_mark();
788
0
        }
789
0
        (void)ERR_set_mark();
790
0
        ctr->cipher_ecb = evp_cipher_fetch_from_prov(prov, ecb, NULL);
791
0
        if (ctr->cipher_ecb == NULL) {
792
0
            (void)ERR_pop_to_mark();
793
0
            ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
794
0
        } else {
795
0
            (void)ERR_clear_last_mark();
796
0
        }
797
0
        OPENSSL_free(ecb);
798
0
        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
0
        cipher_init = 1;
804
0
    }
805
0
    ossl_provider_free(prov);
806
807
0
    if (cipher_init && !drbg_ctr_init(ctx))
808
0
        return 0;
809
810
0
    return ossl_drbg_set_ctx_params(ctx, p);
811
0
}
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
0
{
836
0
    return drbg_ctr_set_ctx_params_list;
837
0
}
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
};