Coverage Report

Created: 2026-10-28 06:28

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