/*
 *  CTR_DRBG implementation based on AES-256 (NIST SP 800-90)
 *
 *  Copyright The Mbed TLS Contributors
 *  SPDX-License-Identifier: Apache-2.0
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
 *  not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
/*
 *  The NIST SP 800-90 DRBGs are described in the following publication.
 *
 *  https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-90r.pdf
 */

#include "common.h"

#if defined(MBEDTLS_CTR_DRBG_C)

#include "mbedtls/ctr_drbg.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"

#include <limits.h>
#include <string.h>

#if defined(MBEDTLS_FS_IO)
#include <stdio.h>
#endif

#include "mbedtls/platform.h"

/*
 * CTR_DRBG context initialization
 */
void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx)
{
    memset(ctx, 0, sizeof(mbedtls_ctr_drbg_context));
    /* Indicate that the entropy nonce length is not set explicitly.
     * See mbedtls_ctr_drbg_set_nonce_len(). */
    ctx->reseed_counter = -1;

    ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
}

/*
 *  This function resets CTR_DRBG context to the state immediately
 *  after initial call of mbedtls_ctr_drbg_init().
 */
void mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context *ctx)
{
    if (ctx == NULL) {
        return;
    }

#if defined(MBEDTLS_THREADING_C)
    /* The mutex is initialized iff f_entropy is set. */
    if (ctx->f_entropy != NULL) {
        mbedtls_mutex_free(&ctx->mutex);
    }
#endif
    mbedtls_aes_free(&ctx->aes_ctx);
    mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ctr_drbg_context));
    ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
    ctx->reseed_counter = -1;
}

void mbedtls_ctr_drbg_set_prediction_resistance(mbedtls_ctr_drbg_context *ctx,
                                                int resistance)
{
    ctx->prediction_resistance = resistance;
}

void mbedtls_ctr_drbg_set_entropy_len(mbedtls_ctr_drbg_context *ctx,
                                      size_t len)
{
    ctx->entropy_len = len;
}

int mbedtls_ctr_drbg_set_nonce_len(mbedtls_ctr_drbg_context *ctx,
                                   size_t len)
{
    /* If mbedtls_ctr_drbg_seed() has already been called, it's
     * too late. Return the error code that's closest to making sense. */
    if (ctx->f_entropy != NULL) {
        return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
    }

    if (len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
    }
#if SIZE_MAX > INT_MAX
    /* This shouldn't be an issue because
     * MBEDTLS_CTR_DRBG_MAX_SEED_INPUT < INT_MAX in any sensible
     * configuration, but make sure anyway. */
    if (len > INT_MAX) {
        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
    }
#endif

    /* For backward compatibility with Mbed TLS <= 2.19, store the
     * entropy nonce length in a field that already exists, but isn't
     * used until after the initial seeding. */
    /* Due to the capping of len above, the value fits in an int. */
    ctx->reseed_counter = (int) len;
    return 0;
}

void mbedtls_ctr_drbg_set_reseed_interval(mbedtls_ctr_drbg_context *ctx,
                                          int interval)
{
    ctx->reseed_interval = interval;
}

static int block_cipher_df(unsigned char *output,
                           const unsigned char *data, size_t data_len)
{
    unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
                      MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
    unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
    unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
    unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
    unsigned char *p, *iv;
    mbedtls_aes_context aes_ctx;
    int ret = 0;

    int i, j;
    size_t buf_len, use_len;

    if (data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
    }

    memset(buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
           MBEDTLS_CTR_DRBG_BLOCKSIZE + 16);
    mbedtls_aes_init(&aes_ctx);

    /*
     * Construct IV (16 bytes) and S in buffer
     * IV = Counter (in 32-bits) padded to 16 with zeroes
     * S = Length input string (in 32-bits) || Length of output (in 32-bits) ||
     *     data || 0x80
     *     (Total is padded to a multiple of 16-bytes with zeroes)
     */
    p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE;
    MBEDTLS_PUT_UINT32_BE(data_len, p, 0);
    p += 4 + 3;
    *p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
    memcpy(p, data, data_len);
    p[data_len] = 0x80;

    buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;

    for (i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++) {
        key[i] = i;
    }

    if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, key,
                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
        goto exit;
    }

    /*
     * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
     */
    for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
        p = buf;
        memset(chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE);
        use_len = buf_len;

        while (use_len > 0) {
            for (i = 0; i < MBEDTLS_CTR_DRBG_BLOCKSIZE; i++) {
                chain[i] ^= p[i];
            }
            p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
            use_len -= (use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE) ?
                       MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;

            if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
                                             chain, chain)) != 0) {
                goto exit;
            }
        }

        memcpy(tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE);

        /*
         * Update IV
         */
        buf[3]++;
    }

    /*
     * Do final encryption with reduced data
     */
    if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp,
                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
        goto exit;
    }
    iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
    p = output;

    for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
        if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
                                         iv, iv)) != 0) {
            goto exit;
        }
        memcpy(p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE);
        p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
    }
exit:
    mbedtls_aes_free(&aes_ctx);
    /*
     * tidy up the stack
     */
    mbedtls_platform_zeroize(buf, sizeof(buf));
    mbedtls_platform_zeroize(tmp, sizeof(tmp));
    mbedtls_platform_zeroize(key, sizeof(key));
    mbedtls_platform_zeroize(chain, sizeof(chain));
    if (0 != ret) {
        /*
         * wipe partial seed from memory
         */
        mbedtls_platform_zeroize(output, MBEDTLS_CTR_DRBG_SEEDLEN);
    }

    return ret;
}

/* CTR_DRBG_Update (SP 800-90A &sect;10.2.1.2)
 * ctr_drbg_update_internal(ctx, provided_data)
 * implements
 * CTR_DRBG_Update(provided_data, Key, V)
 * with inputs and outputs
 *   ctx->aes_ctx = Key
 *   ctx->counter = V
 */
static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
                                    const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN])
{
    unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
    unsigned char *p = tmp;
    int i, j;
    int ret = 0;

    memset(tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN);

    for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
        /*
         * Increase counter
         */
        for (i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i--) {
            if (++ctx->counter[i - 1] != 0) {
                break;
            }
        }

        /*
         * Crypt counter block
         */
        if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
                                         ctx->counter, p)) != 0) {
            goto exit;
        }

        p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
    }

    for (i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++) {
        tmp[i] ^= data[i];
    }

    /*
     * Update key and counter
     */
    if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp,
                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
        goto exit;
    }
    memcpy(ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE,
           MBEDTLS_CTR_DRBG_BLOCKSIZE);

exit:
    mbedtls_platform_zeroize(tmp, sizeof(tmp));
    return ret;
}

/* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
 * mbedtls_ctr_drbg_update(ctx, additional, add_len)
 * implements
 * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
 *                      security_strength) -> initial_working_state
 * with inputs
 *   ctx->counter = all-bits-0
 *   ctx->aes_ctx = context from all-bits-0 key
 *   additional[:add_len] = entropy_input || nonce || personalization_string
 * and with outputs
 *   ctx = initial_working_state
 */
int mbedtls_ctr_drbg_update_ret(mbedtls_ctr_drbg_context *ctx,
                                const unsigned char *additional,
                                size_t add_len)
{
    unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    if (add_len == 0) {
        return 0;
    }

    if ((ret = block_cipher_df(add_input, additional, add_len)) != 0) {
        goto exit;
    }
    if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) {
        goto exit;
    }

exit:
    mbedtls_platform_zeroize(add_input, sizeof(add_input));
    return ret;
}

#if !defined(MBEDTLS_DEPRECATED_REMOVED)
void mbedtls_ctr_drbg_update(mbedtls_ctr_drbg_context *ctx,
                             const unsigned char *additional,
                             size_t add_len)
{
    /* MAX_INPUT would be more logical here, but we have to match
     * block_cipher_df()'s limits since we can't propagate errors */
    if (add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
        add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT;
    }
    (void) mbedtls_ctr_drbg_update_ret(ctx, additional, add_len);
}
#endif /* MBEDTLS_DEPRECATED_REMOVED */

/* CTR_DRBG_Reseed with derivation function (SP 800-90A &sect;10.2.1.4.2)
 * mbedtls_ctr_drbg_reseed(ctx, additional, len, nonce_len)
 * implements
 * CTR_DRBG_Reseed(working_state, entropy_input, additional_input)
 *                -> new_working_state
 * with inputs
 *   ctx contains working_state
 *   additional[:len] = additional_input
 * and entropy_input comes from calling ctx->f_entropy
 *                              for (ctx->entropy_len + nonce_len) bytes
 * and with output
 *   ctx contains new_working_state
 */
static int mbedtls_ctr_drbg_reseed_internal(mbedtls_ctr_drbg_context *ctx,
                                            const unsigned char *additional,
                                            size_t len,
                                            size_t nonce_len)
{
    unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
    size_t seedlen = 0;
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    if (ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
    }
    if (nonce_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len) {
        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
    }
    if (len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len - nonce_len) {
        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
    }

    memset(seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT);

    /* Gather entropy_len bytes of entropy to seed state. */
    if (0 != ctx->f_entropy(ctx->p_entropy, seed, ctx->entropy_len)) {
        return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
    }
    seedlen += ctx->entropy_len;

    /* Gather entropy for a nonce if requested. */
    if (nonce_len != 0) {
        if (0 != ctx->f_entropy(ctx->p_entropy, seed + seedlen, nonce_len)) {
            return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
        }
        seedlen += nonce_len;
    }

    /* Add additional data if provided. */
    if (additional != NULL && len != 0) {
        memcpy(seed + seedlen, additional, len);
        seedlen += len;
    }

    /* Reduce to 384 bits. */
    if ((ret = block_cipher_df(seed, seed, seedlen)) != 0) {
        goto exit;
    }

    /* Update state. */
    if ((ret = ctr_drbg_update_internal(ctx, seed)) != 0) {
        goto exit;
    }
    ctx->reseed_counter = 1;

exit:
    mbedtls_platform_zeroize(seed, sizeof(seed));
    return ret;
}

int mbedtls_ctr_drbg_reseed(mbedtls_ctr_drbg_context *ctx,
                            const unsigned char *additional, size_t len)
{
    return mbedtls_ctr_drbg_reseed_internal(ctx, additional, len, 0);
}

/* Return a "good" nonce length for CTR_DRBG. The chosen nonce length
 * is sufficient to achieve the maximum security strength given the key
 * size and entropy length. If there is enough entropy in the initial
 * call to the entropy function to serve as both the entropy input and
 * the nonce, don't make a second call to get a nonce. */
static size_t good_nonce_len(size_t entropy_len)
{
    if (entropy_len >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2) {
        return 0;
    } else {
        return (entropy_len + 1) / 2;
    }
}

/* CTR_DRBG_Instantiate with derivation function (SP 800-90A &sect;10.2.1.3.2)
 * mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len)
 * implements
 * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
 *                      security_strength) -> initial_working_state
 * with inputs
 *   custom[:len] = nonce || personalization_string
 * where entropy_input comes from f_entropy for ctx->entropy_len bytes
 * and with outputs
 *   ctx = initial_working_state
 */
int mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context *ctx,
                          int (*f_entropy)(void *, unsigned char *, size_t),
                          void *p_entropy,
                          const unsigned char *custom,
                          size_t len)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
    size_t nonce_len;

    memset(key, 0, MBEDTLS_CTR_DRBG_KEYSIZE);

    /* The mutex is initialized iff f_entropy is set. */
#if defined(MBEDTLS_THREADING_C)
    mbedtls_mutex_init(&ctx->mutex);
#endif

    mbedtls_aes_init(&ctx->aes_ctx);

    ctx->f_entropy = f_entropy;
    ctx->p_entropy = p_entropy;

    if (ctx->entropy_len == 0) {
        ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN;
    }
    /* ctx->reseed_counter contains the desired amount of entropy to
     * grab for a nonce (see mbedtls_ctr_drbg_set_nonce_len()).
     * If it's -1, indicating that the entropy nonce length was not set
     * explicitly, use a sufficiently large nonce for security. */
    nonce_len = (ctx->reseed_counter >= 0 ?
                 (size_t) ctx->reseed_counter :
                 good_nonce_len(ctx->entropy_len));

    /* Initialize with an empty key. */
    if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key,
                                      MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
        return ret;
    }

    /* Do the initial seeding. */
    if ((ret = mbedtls_ctr_drbg_reseed_internal(ctx, custom, len,
                                                nonce_len)) != 0) {
        return ret;
    }
    return 0;
}

/* CTR_DRBG_Generate with derivation function (SP 800-90A &sect;10.2.1.5.2)
 * mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len)
 * implements
 * CTR_DRBG_Reseed(working_state, entropy_input, additional[:add_len])
 *                -> working_state_after_reseed
 *                if required, then
 * CTR_DRBG_Generate(working_state_after_reseed,
 *                   requested_number_of_bits, additional_input)
 *                -> status, returned_bits, new_working_state
 * with inputs
 *   ctx contains working_state
 *   requested_number_of_bits = 8 * output_len
 *   additional[:add_len] = additional_input
 * and entropy_input comes from calling ctx->f_entropy
 * and with outputs
 *   status = SUCCESS (this function does the reseed internally)
 *   returned_bits = output[:output_len]
 *   ctx contains new_working_state
 */
int mbedtls_ctr_drbg_random_with_add(void *p_rng,
                                     unsigned char *output, size_t output_len,
                                     const unsigned char *additional, size_t add_len)
{
    int ret = 0;
    mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
    unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
    unsigned char *p = output;
    unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
    int i;
    size_t use_len;

    if (output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST) {
        return MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG;
    }

    if (add_len > MBEDTLS_CTR_DRBG_MAX_INPUT) {
        return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
    }

    memset(add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN);

    if (ctx->reseed_counter > ctx->reseed_interval ||
        ctx->prediction_resistance) {
        if ((ret = mbedtls_ctr_drbg_reseed(ctx, additional, add_len)) != 0) {
            return ret;
        }
        add_len = 0;
    }

    if (add_len > 0) {
        if ((ret = block_cipher_df(add_input, additional, add_len)) != 0) {
            goto exit;
        }
        if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) {
            goto exit;
        }
    }

    while (output_len > 0) {
        /*
         * Increase counter
         */
        for (i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i--) {
            if (++ctx->counter[i - 1] != 0) {
                break;
            }
        }

        /*
         * Crypt counter block
         */
        if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
                                         ctx->counter, tmp)) != 0) {
            goto exit;
        }

        use_len = (output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE)
            ? MBEDTLS_CTR_DRBG_BLOCKSIZE : output_len;
        /*
         * Copy random block to destination
         */
        memcpy(p, tmp, use_len);
        p += use_len;
        output_len -= use_len;
    }

    if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) {
        goto exit;
    }

    ctx->reseed_counter++;

exit:
    mbedtls_platform_zeroize(add_input, sizeof(add_input));
    mbedtls_platform_zeroize(tmp, sizeof(tmp));
    return ret;
}

int mbedtls_ctr_drbg_random(void *p_rng, unsigned char *output,
                            size_t output_len)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;

#if defined(MBEDTLS_THREADING_C)
    if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
        return ret;
    }
#endif

    ret = mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, NULL, 0);

#if defined(MBEDTLS_THREADING_C)
    if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
        return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
    }
#endif

    return ret;
}

#if defined(MBEDTLS_FS_IO)
int mbedtls_ctr_drbg_write_seed_file(mbedtls_ctr_drbg_context *ctx,
                                     const char *path)
{
    int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
    FILE *f;
    unsigned char buf[MBEDTLS_CTR_DRBG_MAX_INPUT];

    if ((f = fopen(path, "wb")) == NULL) {
        return MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
    }

    if ((ret = mbedtls_ctr_drbg_random(ctx, buf,
                                       MBEDTLS_CTR_DRBG_MAX_INPUT)) != 0) {
        goto exit;
    }

    if (fwrite(buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f) !=
        MBEDTLS_CTR_DRBG_MAX_INPUT) {
        ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
    } else {
        ret = 0;
    }

exit:
    mbedtls_platform_zeroize(buf, sizeof(buf));

    fclose(f);
    return ret;
}

int mbedtls_ctr_drbg_update_seed_file(mbedtls_ctr_drbg_context *ctx,
                                      const char *path)
{
    int ret = 0;
    FILE *f = NULL;
    size_t n;
    unsigned char buf[MBEDTLS_CTR_DRBG_MAX_INPUT];
    unsigned char c;

    if ((f = fopen(path, "rb")) == NULL) {
        return MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
    }

    n = fread(buf, 1, sizeof(buf), f);
    if (fread(&c, 1, 1, f) != 0) {
        ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
        goto exit;
    }
    if (n == 0 || ferror(f)) {
        ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
        goto exit;
    }
    fclose(f);
    f = NULL;

    ret = mbedtls_ctr_drbg_update_ret(ctx, buf, n);

exit:
    mbedtls_platform_zeroize(buf, sizeof(buf));
    if (f != NULL) {
        fclose(f);
    }
    if (ret != 0) {
        return ret;
    }
    return mbedtls_ctr_drbg_write_seed_file(ctx, path);
}
#endif /* MBEDTLS_FS_IO */

#if defined(MBEDTLS_SELF_TEST)

/* The CTR_DRBG NIST test vectors used here are available at
 * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/drbg/drbgtestvectors.zip
 *
 * The parameters used to derive the test data are:
 *
 * [AES-128 use df]
 * [PredictionResistance = True/False]
 * [EntropyInputLen = 128]
 * [NonceLen = 64]
 * [PersonalizationStringLen = 128]
 * [AdditionalInputLen = 0]
 * [ReturnedBitsLen = 512]
 *
 * [AES-256 use df]
 * [PredictionResistance = True/False]
 * [EntropyInputLen = 256]
 * [NonceLen = 128]
 * [PersonalizationStringLen = 256]
 * [AdditionalInputLen = 0]
 * [ReturnedBitsLen = 512]
 *
 */

#if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
static const unsigned char entropy_source_pr[] =
{ 0x04, 0xd9, 0x49, 0xa6, 0xdc, 0xe8, 0x6e, 0xbb,
  0xf1, 0x08, 0x77, 0x2b, 0x9e, 0x08, 0xca, 0x92,
  0x65, 0x16, 0xda, 0x99, 0xa2, 0x59, 0xf3, 0xe8,
  0x38, 0x7e, 0x3f, 0x6b, 0x51, 0x70, 0x7b, 0x20,
  0xec, 0x53, 0xd0, 0x66, 0xc3, 0x0f, 0xe3, 0xb0,
  0xe0, 0x86, 0xa6, 0xaa, 0x5f, 0x72, 0x2f, 0xad,
  0xf7, 0xef, 0x06, 0xb8, 0xd6, 0x9c, 0x9d, 0xe8 };

static const unsigned char entropy_source_nopr[] =
{ 0x07, 0x0d, 0x59, 0x63, 0x98, 0x73, 0xa5, 0x45,
  0x27, 0x38, 0x22, 0x7b, 0x76, 0x85, 0xd1, 0xa9,
  0x74, 0x18, 0x1f, 0x3c, 0x22, 0xf6, 0x49, 0x20,
  0x4a, 0x47, 0xc2, 0xf3, 0x85, 0x16, 0xb4, 0x6f,
  0x00, 0x2e, 0x71, 0xda, 0xed, 0x16, 0x9b, 0x5c };

static const unsigned char pers_pr[] =
{ 0xbf, 0xa4, 0x9a, 0x8f, 0x7b, 0xd8, 0xb1, 0x7a,
  0x9d, 0xfa, 0x45, 0xed, 0x21, 0x52, 0xb3, 0xad };

static const unsigned char pers_nopr[] =
{ 0x4e, 0x61, 0x79, 0xd4, 0xc2, 0x72, 0xa1, 0x4c,
  0xf1, 0x3d, 0xf6, 0x5e, 0xa3, 0xa6, 0xe5, 0x0f };

static const unsigned char result_pr[] =
{ 0xc9, 0x0a, 0xaf, 0x85, 0x89, 0x71, 0x44, 0x66,
  0x4f, 0x25, 0x0b, 0x2b, 0xde, 0xd8, 0xfa, 0xff,
  0x52, 0x5a, 0x1b, 0x32, 0x5e, 0x41, 0x7a, 0x10,
  0x1f, 0xef, 0x1e, 0x62, 0x23, 0xe9, 0x20, 0x30,
  0xc9, 0x0d, 0xad, 0x69, 0xb4, 0x9c, 0x5b, 0xf4,
  0x87, 0x42, 0xd5, 0xae, 0x5e, 0x5e, 0x43, 0xcc,
  0xd9, 0xfd, 0x0b, 0x93, 0x4a, 0xe3, 0xd4, 0x06,
  0x37, 0x36, 0x0f, 0x3f, 0x72, 0x82, 0x0c, 0xcf };

static const unsigned char result_nopr[] =
{ 0x31, 0xc9, 0x91, 0x09, 0xf8, 0xc5, 0x10, 0x13,
  0x3c, 0xd3, 0x96, 0xf9, 0xbc, 0x2c, 0x12, 0xc0,
  0x7c, 0xc1, 0x61, 0x5f, 0xa3, 0x09, 0x99, 0xaf,
  0xd7, 0xf2, 0x36, 0xfd, 0x40, 0x1a, 0x8b, 0xf2,
  0x33, 0x38, 0xee, 0x1d, 0x03, 0x5f, 0x83, 0xb7,
  0xa2, 0x53, 0xdc, 0xee, 0x18, 0xfc, 0xa7, 0xf2,
  0xee, 0x96, 0xc6, 0xc2, 0xcd, 0x0c, 0xff, 0x02,
  0x76, 0x70, 0x69, 0xaa, 0x69, 0xd1, 0x3b, 0xe8 };
#else /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */

static const unsigned char entropy_source_pr[] =
{ 0xca, 0x58, 0xfd, 0xf2, 0xb9, 0x77, 0xcb, 0x49,
  0xd4, 0xe0, 0x5b, 0xe2, 0x39, 0x50, 0xd9, 0x8a,
  0x6a, 0xb3, 0xc5, 0x2f, 0xdf, 0x74, 0xd5, 0x85,
  0x8f, 0xd1, 0xba, 0x64, 0x54, 0x7b, 0xdb, 0x1e,
  0xc5, 0xea, 0x24, 0xc0, 0xfa, 0x0c, 0x90, 0x15,
  0x09, 0x20, 0x92, 0x42, 0x32, 0x36, 0x45, 0x45,
  0x7d, 0x20, 0x76, 0x6b, 0xcf, 0xa2, 0x15, 0xc8,
  0x2f, 0x9f, 0xbc, 0x88, 0x3f, 0x80, 0xd1, 0x2c,
  0xb7, 0x16, 0xd1, 0x80, 0x9e, 0xe1, 0xc9, 0xb3,
  0x88, 0x1b, 0x21, 0x45, 0xef, 0xa1, 0x7f, 0xce,
  0xc8, 0x92, 0x35, 0x55, 0x2a, 0xd9, 0x1d, 0x8e,
  0x12, 0x38, 0xac, 0x01, 0x4e, 0x38, 0x18, 0x76,
  0x9c, 0xf2, 0xb6, 0xd4, 0x13, 0xb6, 0x2c, 0x77,
  0xc0, 0xe7, 0xe6, 0x0c, 0x47, 0x44, 0x95, 0xbe };

static const unsigned char entropy_source_nopr[] =
{ 0x4c, 0xfb, 0x21, 0x86, 0x73, 0x34, 0x6d, 0x9d,
  0x50, 0xc9, 0x22, 0xe4, 0x9b, 0x0d, 0xfc, 0xd0,
  0x90, 0xad, 0xf0, 0x4f, 0x5c, 0x3b, 0xa4, 0x73,
  0x27, 0xdf, 0xcd, 0x6f, 0xa6, 0x3a, 0x78, 0x5c,
  0x01, 0x69, 0x62, 0xa7, 0xfd, 0x27, 0x87, 0xa2,
  0x4b, 0xf6, 0xbe, 0x47, 0xef, 0x37, 0x83, 0xf1,
  0xb7, 0xec, 0x46, 0x07, 0x23, 0x63, 0x83, 0x4a,
  0x1b, 0x01, 0x33, 0xf2, 0xc2, 0x38, 0x91, 0xdb,
  0x4f, 0x11, 0xa6, 0x86, 0x51, 0xf2, 0x3e, 0x3a,
  0x8b, 0x1f, 0xdc, 0x03, 0xb1, 0x92, 0xc7, 0xe7 };

static const unsigned char pers_pr[] =
{ 0x5a, 0x70, 0x95, 0xe9, 0x81, 0x40, 0x52, 0x33,
  0x91, 0x53, 0x7e, 0x75, 0xd6, 0x19, 0x9d, 0x1e,
  0xad, 0x0d, 0xc6, 0xa7, 0xde, 0x6c, 0x1f, 0xe0,
  0xea, 0x18, 0x33, 0xa8, 0x7e, 0x06, 0x20, 0xe9 };

static const unsigned char pers_nopr[] =
{ 0x88, 0xee, 0xb8, 0xe0, 0xe8, 0x3b, 0xf3, 0x29,
  0x4b, 0xda, 0xcd, 0x60, 0x99, 0xeb, 0xe4, 0xbf,
  0x55, 0xec, 0xd9, 0x11, 0x3f, 0x71, 0xe5, 0xeb,
  0xcb, 0x45, 0x75, 0xf3, 0xd6, 0xa6, 0x8a, 0x6b };

static const unsigned char result_pr[] =
{ 0xce, 0x2f, 0xdb, 0xb6, 0xd9, 0xb7, 0x39, 0x85,
  0x04, 0xc5, 0xc0, 0x42, 0xc2, 0x31, 0xc6, 0x1d,
  0x9b, 0x5a, 0x59, 0xf8, 0x7e, 0x0d, 0xcc, 0x62,
  0x7b, 0x65, 0x11, 0x55, 0x10, 0xeb, 0x9e, 0x3d,
  0xa4, 0xfb, 0x1c, 0x6a, 0x18, 0xc0, 0x74, 0xdb,
  0xdd, 0xe7, 0x02, 0x23, 0x63, 0x21, 0xd0, 0x39,
  0xf9, 0xa7, 0xc4, 0x52, 0x84, 0x3b, 0x49, 0x40,
  0x72, 0x2b, 0xb0, 0x6c, 0x9c, 0xdb, 0xc3, 0x43 };

static const unsigned char result_nopr[] =
{ 0xa5, 0x51, 0x80, 0xa1, 0x90, 0xbe, 0xf3, 0xad,
  0xaf, 0x28, 0xf6, 0xb7, 0x95, 0xe9, 0xf1, 0xf3,
  0xd6, 0xdf, 0xa1, 0xb2, 0x7d, 0xd0, 0x46, 0x7b,
  0x0c, 0x75, 0xf5, 0xfa, 0x93, 0x1e, 0x97, 0x14,
  0x75, 0xb2, 0x7c, 0xae, 0x03, 0xa2, 0x96, 0x54,
  0xe2, 0xf4, 0x09, 0x66, 0xea, 0x33, 0x64, 0x30,
  0x40, 0xd1, 0x40, 0x0f, 0xe6, 0x77, 0x87, 0x3a,
  0xf8, 0x09, 0x7c, 0x1f, 0xe9, 0xf0, 0x02, 0x98 };
#endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */

static size_t test_offset;
static int ctr_drbg_self_test_entropy(void *data, unsigned char *buf,
                                      size_t len)
{
    const unsigned char *p = data;
    memcpy(buf, p + test_offset, len);
    test_offset += len;
    return 0;
}

#define CHK(c)    if ((c) != 0)                          \
    {                                       \
        if (verbose != 0)                  \
        mbedtls_printf("failed\n");  \
        return 1;                        \
    }

#define SELF_TEST_OUTPUT_DISCARD_LENGTH 64

/*
 * Checkup routine
 */
int mbedtls_ctr_drbg_self_test(int verbose)
{
    mbedtls_ctr_drbg_context ctx;
    unsigned char buf[sizeof(result_pr)];

    mbedtls_ctr_drbg_init(&ctx);

    /*
     * Based on a NIST CTR_DRBG test vector (PR = True)
     */
    if (verbose != 0) {
        mbedtls_printf("  CTR_DRBG (PR = TRUE) : ");
    }

    test_offset = 0;
    mbedtls_ctr_drbg_set_entropy_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE);
    mbedtls_ctr_drbg_set_nonce_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2);
    CHK(mbedtls_ctr_drbg_seed(&ctx,
                              ctr_drbg_self_test_entropy,
                              (void *) entropy_source_pr,
                              pers_pr, MBEDTLS_CTR_DRBG_KEYSIZE));
    mbedtls_ctr_drbg_set_prediction_resistance(&ctx, MBEDTLS_CTR_DRBG_PR_ON);
    CHK(mbedtls_ctr_drbg_random(&ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH));
    CHK(mbedtls_ctr_drbg_random(&ctx, buf, sizeof(result_pr)));
    CHK(memcmp(buf, result_pr, sizeof(result_pr)));

    mbedtls_ctr_drbg_free(&ctx);

    if (verbose != 0) {
        mbedtls_printf("passed\n");
    }

    /*
     * Based on a NIST CTR_DRBG test vector (PR = FALSE)
     */
    if (verbose != 0) {
        mbedtls_printf("  CTR_DRBG (PR = FALSE): ");
    }

    mbedtls_ctr_drbg_init(&ctx);

    test_offset = 0;
    mbedtls_ctr_drbg_set_entropy_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE);
    mbedtls_ctr_drbg_set_nonce_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2);
    CHK(mbedtls_ctr_drbg_seed(&ctx,
                              ctr_drbg_self_test_entropy,
                              (void *) entropy_source_nopr,
                              pers_nopr, MBEDTLS_CTR_DRBG_KEYSIZE));
    CHK(mbedtls_ctr_drbg_reseed(&ctx, NULL, 0));
    CHK(mbedtls_ctr_drbg_random(&ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH));
    CHK(mbedtls_ctr_drbg_random(&ctx, buf, sizeof(result_nopr)));
    CHK(memcmp(buf, result_nopr, sizeof(result_nopr)));

    mbedtls_ctr_drbg_free(&ctx);

    if (verbose != 0) {
        mbedtls_printf("passed\n");
    }

    if (verbose != 0) {
        mbedtls_printf("\n");
    }

    return 0;
}
#endif /* MBEDTLS_SELF_TEST */

#endif /* MBEDTLS_CTR_DRBG_C */
