/*
 * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <stdlib.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/aes.h>
#include <openssl/proverr.h>
#include "internal/e_os.h" /* strcasecmp */
#include "crypto/modes.h"
#include "internal/thread_once.h"
#include "prov/implementations.h"
#include "prov/providercommon.h"
#include "prov/provider_ctx.h"
#include "drbg_local.h"

static OSSL_FUNC_rand_newctx_fn drbg_ctr_new_wrapper;
static OSSL_FUNC_rand_freectx_fn drbg_ctr_free;
static OSSL_FUNC_rand_instantiate_fn drbg_ctr_instantiate_wrapper;
static OSSL_FUNC_rand_uninstantiate_fn drbg_ctr_uninstantiate_wrapper;
static OSSL_FUNC_rand_generate_fn drbg_ctr_generate_wrapper;
static OSSL_FUNC_rand_reseed_fn drbg_ctr_reseed_wrapper;
static OSSL_FUNC_rand_settable_ctx_params_fn drbg_ctr_settable_ctx_params;
static OSSL_FUNC_rand_set_ctx_params_fn drbg_ctr_set_ctx_params;
static OSSL_FUNC_rand_gettable_ctx_params_fn drbg_ctr_gettable_ctx_params;
static OSSL_FUNC_rand_get_ctx_params_fn drbg_ctr_get_ctx_params;
static OSSL_FUNC_rand_verify_zeroization_fn drbg_ctr_verify_zeroization;

/*
 * The state of a DRBG AES-CTR.
 */
typedef struct rand_drbg_ctr_st {
    EVP_CIPHER_CTX *ctx_ecb;
    EVP_CIPHER_CTX *ctx_ctr;
    EVP_CIPHER_CTX *ctx_df;
    EVP_CIPHER *cipher_ecb;
    EVP_CIPHER *cipher_ctr;
    size_t keylen;
    int use_df;
    unsigned char K[32];
    unsigned char V[16];
    /* Temporary block storage used by ctr_df */
    unsigned char bltmp[16];
    size_t bltmp_pos;
    unsigned char KX[48];
} PROV_DRBG_CTR;

/*
 * Implementation of NIST SP 800-90A CTR DRBG.
 */
static void inc_128(PROV_DRBG_CTR *ctr)
{
    unsigned char *p = &ctr->V[0];
    u32 n = 16, c = 1;

    do {
        --n;
        c += p[n];
        p[n] = (u8)c;
        c >>= 8;
    } while (n);
}

static void ctr_XOR(PROV_DRBG_CTR *ctr, const unsigned char *in, size_t inlen)
{
    size_t i, n;

    if (in == NULL || inlen == 0)
        return;

    /*
     * Any zero padding will have no effect on the result as we
     * are XORing. So just process however much input we have.
     */
    n = inlen < ctr->keylen ? inlen : ctr->keylen;
    for (i = 0; i < n; i++)
        ctr->K[i] ^= in[i];
    if (inlen <= ctr->keylen)
        return;

    n = inlen - ctr->keylen;
    if (n > 16) {
        /* Should never happen */
        n = 16;
    }
    for (i = 0; i < n; i++)
        ctr->V[i] ^= in[i + ctr->keylen];
}

/*
 * Process a complete block using BCC algorithm of SP 800-90A 10.3.3
 */
__owur static int ctr_BCC_block(PROV_DRBG_CTR *ctr, unsigned char *out,
                                const unsigned char *in, int len)
{
    int i, outlen = AES_BLOCK_SIZE;

    for (i = 0; i < len; i++)
        out[i] ^= in[i];

    if (!EVP_CipherUpdate(ctr->ctx_df, out, &outlen, out, len)
        || outlen != len)
        return 0;
    return 1;
}


/*
 * Handle several BCC operations for as much data as we need for K and X
 */
__owur static int ctr_BCC_blocks(PROV_DRBG_CTR *ctr, const unsigned char *in)
{
    unsigned char in_tmp[48];
    unsigned char num_of_blk = 2;

    memcpy(in_tmp, in, 16);
    memcpy(in_tmp + 16, in, 16);
    if (ctr->keylen != 16) {
        memcpy(in_tmp + 32, in, 16);
        num_of_blk = 3;
    }
    return ctr_BCC_block(ctr, ctr->KX, in_tmp, AES_BLOCK_SIZE * num_of_blk);
}

/*
 * Initialise BCC blocks: these have the value 0,1,2 in leftmost positions:
 * see 10.3.1 stage 7.
 */
__owur static int ctr_BCC_init(PROV_DRBG_CTR *ctr)
{
    unsigned char bltmp[48] = {0};
    unsigned char num_of_blk;

    memset(ctr->KX, 0, 48);
    num_of_blk = ctr->keylen == 16 ? 2 : 3;
    bltmp[(AES_BLOCK_SIZE * 1) + 3] = 1;
    bltmp[(AES_BLOCK_SIZE * 2) + 3] = 2;
    return ctr_BCC_block(ctr, ctr->KX, bltmp, num_of_blk * AES_BLOCK_SIZE);
}

/*
 * Process several blocks into BCC algorithm, some possibly partial
 */
__owur static int ctr_BCC_update(PROV_DRBG_CTR *ctr,
                                 const unsigned char *in, size_t inlen)
{
    if (in == NULL || inlen == 0)
        return 1;

    /* If we have partial block handle it first */
    if (ctr->bltmp_pos) {
        size_t left = 16 - ctr->bltmp_pos;

        /* If we now have a complete block process it */
        if (inlen >= left) {
            memcpy(ctr->bltmp + ctr->bltmp_pos, in, left);
            if (!ctr_BCC_blocks(ctr, ctr->bltmp))
                return 0;
            ctr->bltmp_pos = 0;
            inlen -= left;
            in += left;
        }
    }

    /* Process zero or more complete blocks */
    for (; inlen >= 16; in += 16, inlen -= 16) {
        if (!ctr_BCC_blocks(ctr, in))
            return 0;
    }

    /* Copy any remaining partial block to the temporary buffer */
    if (inlen > 0) {
        memcpy(ctr->bltmp + ctr->bltmp_pos, in, inlen);
        ctr->bltmp_pos += inlen;
    }
    return 1;
}

__owur static int ctr_BCC_final(PROV_DRBG_CTR *ctr)
{
    if (ctr->bltmp_pos) {
        memset(ctr->bltmp + ctr->bltmp_pos, 0, 16 - ctr->bltmp_pos);
        if (!ctr_BCC_blocks(ctr, ctr->bltmp))
            return 0;
    }
    return 1;
}

__owur static int ctr_df(PROV_DRBG_CTR *ctr,
                         const unsigned char *in1, size_t in1len,
                         const unsigned char *in2, size_t in2len,
                         const unsigned char *in3, size_t in3len)
{
    static unsigned char c80 = 0x80;
    size_t inlen;
    unsigned char *p = ctr->bltmp;
    int outlen = AES_BLOCK_SIZE;

    if (!ctr_BCC_init(ctr))
        return 0;
    if (in1 == NULL)
        in1len = 0;
    if (in2 == NULL)
        in2len = 0;
    if (in3 == NULL)
        in3len = 0;
    inlen = in1len + in2len + in3len;
    /* Initialise L||N in temporary block */
    *p++ = (inlen >> 24) & 0xff;
    *p++ = (inlen >> 16) & 0xff;
    *p++ = (inlen >> 8) & 0xff;
    *p++ = inlen & 0xff;

    /* NB keylen is at most 32 bytes */
    *p++ = 0;
    *p++ = 0;
    *p++ = 0;
    *p = (unsigned char)((ctr->keylen + 16) & 0xff);
    ctr->bltmp_pos = 8;
    if (!ctr_BCC_update(ctr, in1, in1len)
        || !ctr_BCC_update(ctr, in2, in2len)
        || !ctr_BCC_update(ctr, in3, in3len)
        || !ctr_BCC_update(ctr, &c80, 1)
        || !ctr_BCC_final(ctr))
        return 0;
    /* Set up key K */
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->KX, NULL, -1))
        return 0;
    /* X follows key K */
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX, &outlen, ctr->KX + ctr->keylen,
                          AES_BLOCK_SIZE)
        || outlen != AES_BLOCK_SIZE)
        return 0;
    if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 16, &outlen, ctr->KX,
                          AES_BLOCK_SIZE)
        || outlen != AES_BLOCK_SIZE)
        return 0;
    if (ctr->keylen != 16)
        if (!EVP_CipherUpdate(ctr->ctx_ecb, ctr->KX + 32, &outlen,
                              ctr->KX + 16, AES_BLOCK_SIZE)
            || outlen != AES_BLOCK_SIZE)
            return 0;
    return 1;
}

/*
 * NB the no-df Update in SP800-90A specifies a constant input length
 * of seedlen, however other uses of this algorithm pad the input with
 * zeroes if necessary and have up to two parameters XORed together,
 * so we handle both cases in this function instead.
 */
__owur static int ctr_update(PROV_DRBG *drbg,
                             const unsigned char *in1, size_t in1len,
                             const unsigned char *in2, size_t in2len,
                             const unsigned char *nonce, size_t noncelen)
{
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
    int outlen = AES_BLOCK_SIZE;
    unsigned char V_tmp[48], out[48];
    unsigned char len;

    /* correct key is already set up. */
    memcpy(V_tmp, ctr->V, 16);
    inc_128(ctr);
    memcpy(V_tmp + 16, ctr->V, 16);
    if (ctr->keylen == 16) {
        len = 32;
    } else {
        inc_128(ctr);
        memcpy(V_tmp + 32, ctr->V, 16);
        len = 48;
    }
    if (!EVP_CipherUpdate(ctr->ctx_ecb, out, &outlen, V_tmp, len)
            || outlen != len)
        return 0;
    memcpy(ctr->K, out, ctr->keylen);
    memcpy(ctr->V, out + ctr->keylen, 16);

    if (ctr->use_df) {
        /* If no input reuse existing derived value */
        if (in1 != NULL || nonce != NULL || in2 != NULL)
            if (!ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len))
                return 0;
        /* If this a reuse input in1len != 0 */
        if (in1len)
            ctr_XOR(ctr, ctr->KX, drbg->seedlen);
    } else {
        ctr_XOR(ctr, in1, in1len);
        ctr_XOR(ctr, in2, in2len);
    }

    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1)
        || !EVP_CipherInit_ex(ctr->ctx_ctr, NULL, NULL, ctr->K, NULL, -1))
        return 0;
    return 1;
}

static int drbg_ctr_instantiate(PROV_DRBG *drbg,
                                const unsigned char *entropy, size_t entropylen,
                                const unsigned char *nonce, size_t noncelen,
                                const unsigned char *pers, size_t perslen)
{
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;

    if (entropy == NULL)
        return 0;

    memset(ctr->K, 0, sizeof(ctr->K));
    memset(ctr->V, 0, sizeof(ctr->V));
    if (!EVP_CipherInit_ex(ctr->ctx_ecb, NULL, NULL, ctr->K, NULL, -1))
        return 0;

    inc_128(ctr);
    if (!ctr_update(drbg, entropy, entropylen, pers, perslen, nonce, noncelen))
        return 0;
    return 1;
}

static int drbg_ctr_instantiate_wrapper(void *vdrbg, unsigned int strength,
                                        int prediction_resistance,
                                        const unsigned char *pstr,
                                        size_t pstr_len,
                                        const OSSL_PARAM params[])
{
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;

    if (!ossl_prov_is_running() || !drbg_ctr_set_ctx_params(drbg, params))
        return 0;
    return ossl_prov_drbg_instantiate(drbg, strength, prediction_resistance,
                                      pstr, pstr_len);
}

static int drbg_ctr_reseed(PROV_DRBG *drbg,
                           const unsigned char *entropy, size_t entropylen,
                           const unsigned char *adin, size_t adinlen)
{
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;

    if (entropy == NULL)
        return 0;

    inc_128(ctr);
    if (!ctr_update(drbg, entropy, entropylen, adin, adinlen, NULL, 0))
        return 0;
    return 1;
}

static int drbg_ctr_reseed_wrapper(void *vdrbg, int prediction_resistance,
                                   const unsigned char *ent, size_t ent_len,
                                   const unsigned char *adin, size_t adin_len)
{
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;

    return ossl_prov_drbg_reseed(drbg, prediction_resistance, ent, ent_len,
                                 adin, adin_len);
}

static void ctr96_inc(unsigned char *counter)
{
    u32 n = 12, c = 1;

    do {
        --n;
        c += counter[n];
        counter[n] = (u8)c;
        c >>= 8;
    } while (n);
}

static int drbg_ctr_generate(PROV_DRBG *drbg,
                             unsigned char *out, size_t outlen,
                             const unsigned char *adin, size_t adinlen)
{
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
    unsigned int ctr32, blocks;
    int outl, buflen;

    if (adin != NULL && adinlen != 0) {
        inc_128(ctr);

        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
            return 0;
        /* This means we reuse derived value */
        if (ctr->use_df) {
            adin = NULL;
            adinlen = 1;
        }
    } else {
        adinlen = 0;
    }

    inc_128(ctr);

    if (outlen == 0) {
        inc_128(ctr);

        if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
            return 0;
        return 1;
    }

    memset(out, 0, outlen);

    do {
        if (!EVP_CipherInit_ex(ctr->ctx_ctr,
                               NULL, NULL, NULL, ctr->V, -1))
            return 0;

        /*-
         * outlen has type size_t while EVP_CipherUpdate takes an
         * int argument and thus cannot be guaranteed to process more
         * than 2^31-1 bytes at a time. We process such huge generate
         * requests in 2^30 byte chunks, which is the greatest multiple
         * of AES block size lower than or equal to 2^31-1.
         */
        buflen = outlen > (1U << 30) ? (1U << 30) : outlen;
        blocks = (buflen + 15) / 16;

        ctr32 = GETU32(ctr->V + 12) + blocks;
        if (ctr32 < blocks) {
            /* 32-bit counter overflow into V. */
            if (ctr32 != 0) {
                blocks -= ctr32;
                buflen = blocks * 16;
                ctr32 = 0;
            }
            ctr96_inc(ctr->V);
        }
        PUTU32(ctr->V + 12, ctr32);

        if (!EVP_CipherUpdate(ctr->ctx_ctr, out, &outl, out, buflen)
            || outl != buflen)
            return 0;

        out += buflen;
        outlen -= buflen;
    } while (outlen);

    if (!ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0))
        return 0;
    return 1;
}

static int drbg_ctr_generate_wrapper
    (void *vdrbg, unsigned char *out, size_t outlen,
     unsigned int strength, int prediction_resistance,
     const unsigned char *adin, size_t adin_len)
{
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;

    return ossl_prov_drbg_generate(drbg, out, outlen, strength,
                                   prediction_resistance, adin, adin_len);
}

static int drbg_ctr_uninstantiate(PROV_DRBG *drbg)
{
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;

    OPENSSL_cleanse(ctr->K, sizeof(ctr->K));
    OPENSSL_cleanse(ctr->V, sizeof(ctr->V));
    OPENSSL_cleanse(ctr->bltmp, sizeof(ctr->bltmp));
    OPENSSL_cleanse(ctr->KX, sizeof(ctr->KX));
    ctr->bltmp_pos = 0;
    return ossl_prov_drbg_uninstantiate(drbg);
}

static int drbg_ctr_uninstantiate_wrapper(void *vdrbg)
{
    return drbg_ctr_uninstantiate((PROV_DRBG *)vdrbg);
}

static int drbg_ctr_verify_zeroization(void *vdrbg)
{
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;

    PROV_DRBG_VERYIFY_ZEROIZATION(ctr->K);
    PROV_DRBG_VERYIFY_ZEROIZATION(ctr->V);
    PROV_DRBG_VERYIFY_ZEROIZATION(ctr->bltmp);
    PROV_DRBG_VERYIFY_ZEROIZATION(ctr->KX);
    if (ctr->bltmp_pos != 0)
        return 0;
    return 1;
}

static int drbg_ctr_init_lengths(PROV_DRBG *drbg)
{
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
    int res = 1;

    /* Maximum number of bits per request = 2^19  = 2^16 bytes */
    drbg->max_request = 1 << 16;
    if (ctr->use_df) {
        drbg->min_entropylen = 0;
        drbg->max_entropylen = DRBG_MAX_LENGTH;
        drbg->min_noncelen = 0;
        drbg->max_noncelen = DRBG_MAX_LENGTH;
        drbg->max_perslen = DRBG_MAX_LENGTH;
        drbg->max_adinlen = DRBG_MAX_LENGTH;

        if (ctr->keylen > 0) {
            drbg->min_entropylen = ctr->keylen;
            drbg->min_noncelen = drbg->min_entropylen / 2;
        }
    } else {
        const size_t len = ctr->keylen > 0 ? drbg->seedlen : DRBG_MAX_LENGTH;

        drbg->min_entropylen = len;
        drbg->max_entropylen = len;
        /* Nonce not used */
        drbg->min_noncelen = 0;
        drbg->max_noncelen = 0;
        drbg->max_perslen = len;
        drbg->max_adinlen = len;
    }
    return res;
}

static int drbg_ctr_init(PROV_DRBG *drbg)
{
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
    size_t keylen;

    if (ctr->cipher_ctr == NULL) {
        ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CIPHER);
        return 0;
    }
    ctr->keylen = keylen = EVP_CIPHER_get_key_length(ctr->cipher_ctr);
    if (ctr->ctx_ecb == NULL)
        ctr->ctx_ecb = EVP_CIPHER_CTX_new();
    if (ctr->ctx_ctr == NULL)
        ctr->ctx_ctr = EVP_CIPHER_CTX_new();
    if (ctr->ctx_ecb == NULL || ctr->ctx_ctr == NULL) {
        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    if (!EVP_CipherInit_ex(ctr->ctx_ecb,
                           ctr->cipher_ecb, NULL, NULL, NULL, 1)
        || !EVP_CipherInit_ex(ctr->ctx_ctr,
                              ctr->cipher_ctr, NULL, NULL, NULL, 1)) {
        ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_INITIALISE_CIPHERS);
        goto err;
    }

    drbg->strength = keylen * 8;
    drbg->seedlen = keylen + 16;

    if (ctr->use_df) {
        /* df initialisation */
        static const unsigned char df_key[32] = {
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
            0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
            0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
            0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
        };

        if (ctr->ctx_df == NULL)
            ctr->ctx_df = EVP_CIPHER_CTX_new();
        if (ctr->ctx_df == NULL) {
            ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
            goto err;
        }
        /* Set key schedule for df_key */
        if (!EVP_CipherInit_ex(ctr->ctx_df,
                               ctr->cipher_ecb, NULL, df_key, NULL, 1)) {
            ERR_raise(ERR_LIB_PROV, PROV_R_DERIVATION_FUNCTION_INIT_FAILED);
            goto err;
        }
    }
    return drbg_ctr_init_lengths(drbg);

err:
    EVP_CIPHER_CTX_free(ctr->ctx_ecb);
    EVP_CIPHER_CTX_free(ctr->ctx_ctr);
    ctr->ctx_ecb = ctr->ctx_ctr = NULL;
    return 0;    
}

static int drbg_ctr_new(PROV_DRBG *drbg)
{
    PROV_DRBG_CTR *ctr;

    ctr = OPENSSL_secure_zalloc(sizeof(*ctr));
    if (ctr == NULL) {
        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
        return 0;
    }

    ctr->use_df = 1;
    drbg->data = ctr;
    return drbg_ctr_init_lengths(drbg);
}

static void *drbg_ctr_new_wrapper(void *provctx, void *parent,
                                   const OSSL_DISPATCH *parent_dispatch)
{
    return ossl_rand_drbg_new(provctx, parent, parent_dispatch, &drbg_ctr_new,
                              &drbg_ctr_instantiate, &drbg_ctr_uninstantiate,
                              &drbg_ctr_reseed, &drbg_ctr_generate);
}

static void drbg_ctr_free(void *vdrbg)
{
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
    PROV_DRBG_CTR *ctr;

    if (drbg != NULL && (ctr = (PROV_DRBG_CTR *)drbg->data) != NULL) {
        EVP_CIPHER_CTX_free(ctr->ctx_ecb);
        EVP_CIPHER_CTX_free(ctr->ctx_ctr);
        EVP_CIPHER_CTX_free(ctr->ctx_df);
        EVP_CIPHER_free(ctr->cipher_ecb);
        EVP_CIPHER_free(ctr->cipher_ctr);

        OPENSSL_secure_clear_free(ctr, sizeof(*ctr));
    }
    ossl_rand_drbg_free(drbg);
}

static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
{
    PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
    OSSL_PARAM *p;

    p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_USE_DF);
    if (p != NULL && !OSSL_PARAM_set_int(p, ctr->use_df))
        return 0;

    p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_CIPHER);
    if (p != NULL) {
        if (ctr->cipher_ctr == NULL
            || !OSSL_PARAM_set_utf8_string(p,
                                           EVP_CIPHER_get0_name(ctr->cipher_ctr)))
            return 0;
    }

    return ossl_drbg_get_ctx_params(drbg, params);
}

static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *vctx,
                                                      ossl_unused void *provctx)
{
    static const OSSL_PARAM known_gettable_ctx_params[] = {
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
        OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
        OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON,
        OSSL_PARAM_END
    };
    return known_gettable_ctx_params;
}

static int drbg_ctr_set_ctx_params(void *vctx, const OSSL_PARAM params[])
{
    PROV_DRBG *ctx = (PROV_DRBG *)vctx;
    PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data;
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
    const OSSL_PARAM *p;
    char *ecb;
    const char *propquery = NULL;
    int i, cipher_init = 0;

    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_USE_DF)) != NULL
            && OSSL_PARAM_get_int(p, &i)) {
        /* FIPS errors out in the drbg_ctr_init() call later */
        ctr->use_df = i != 0;
        cipher_init = 1;
    }

    if ((p = OSSL_PARAM_locate_const(params,
                                     OSSL_DRBG_PARAM_PROPERTIES)) != NULL) {
        if (p->data_type != OSSL_PARAM_UTF8_STRING)
            return 0;
        propquery = (const char *)p->data;
    }

    if ((p = OSSL_PARAM_locate_const(params, OSSL_DRBG_PARAM_CIPHER)) != NULL) {
        const char *base = (const char *)p->data;
        size_t ctr_str_len = sizeof("CTR") - 1;
        size_t ecb_str_len = sizeof("ECB") - 1;

        if (p->data_type != OSSL_PARAM_UTF8_STRING
                || p->data_size < ctr_str_len)
            return 0;
        if (strcasecmp("CTR", base + p->data_size - ctr_str_len) != 0) {
            ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER);
            return 0;
        }
        if ((ecb = OPENSSL_strndup(base, p->data_size)) == NULL) {
            ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
            return 0;
        }
        strcpy(ecb + p->data_size - ecb_str_len, "ECB");
        EVP_CIPHER_free(ctr->cipher_ecb);
        EVP_CIPHER_free(ctr->cipher_ctr);
        ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery);
        ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery);
        OPENSSL_free(ecb);
        if (ctr->cipher_ctr == NULL || ctr->cipher_ecb == NULL) {
            ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_FIND_CIPHERS);
            return 0;
        }
        cipher_init = 1;
    }

    if (cipher_init && !drbg_ctr_init(ctx))
        return 0;

    return ossl_drbg_set_ctx_params(ctx, params);
}

static const OSSL_PARAM *drbg_ctr_settable_ctx_params(ossl_unused void *vctx,
                                                      ossl_unused void *provctx)
{
    static const OSSL_PARAM known_settable_ctx_params[] = {
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, NULL, 0),
        OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
        OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
        OSSL_PARAM_DRBG_SETTABLE_CTX_COMMON,
        OSSL_PARAM_END
    };
    return known_settable_ctx_params;
}

const OSSL_DISPATCH ossl_drbg_ctr_functions[] = {
    { OSSL_FUNC_RAND_NEWCTX, (void(*)(void))drbg_ctr_new_wrapper },
    { OSSL_FUNC_RAND_FREECTX, (void(*)(void))drbg_ctr_free },
    { OSSL_FUNC_RAND_INSTANTIATE,
      (void(*)(void))drbg_ctr_instantiate_wrapper },
    { OSSL_FUNC_RAND_UNINSTANTIATE,
      (void(*)(void))drbg_ctr_uninstantiate_wrapper },
    { OSSL_FUNC_RAND_GENERATE, (void(*)(void))drbg_ctr_generate_wrapper },
    { OSSL_FUNC_RAND_RESEED, (void(*)(void))drbg_ctr_reseed_wrapper },
    { OSSL_FUNC_RAND_ENABLE_LOCKING, (void(*)(void))ossl_drbg_enable_locking },
    { OSSL_FUNC_RAND_LOCK, (void(*)(void))ossl_drbg_lock },
    { OSSL_FUNC_RAND_UNLOCK, (void(*)(void))ossl_drbg_unlock },
    { OSSL_FUNC_RAND_SETTABLE_CTX_PARAMS,
      (void(*)(void))drbg_ctr_settable_ctx_params },
    { OSSL_FUNC_RAND_SET_CTX_PARAMS, (void(*)(void))drbg_ctr_set_ctx_params },
    { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
      (void(*)(void))drbg_ctr_gettable_ctx_params },
    { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))drbg_ctr_get_ctx_params },
    { OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
      (void(*)(void))drbg_ctr_verify_zeroization },
    { OSSL_FUNC_RAND_GET_SEED, (void(*)(void))ossl_drbg_get_seed },
    { OSSL_FUNC_RAND_CLEAR_SEED, (void(*)(void))ossl_drbg_clear_seed },
    { 0, NULL }
};
