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