Coverage Report

Created: 2026-09-12 06:55

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