/*
 * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright (c) 2019, Oracle and/or its affiliates.  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
 */

/*
 * Implementation of the FIPS 140-2 section 4.9.2 Conditional Tests.
 */

#include <string.h>
#include <openssl/evp.h>
#include <openssl/core_dispatch.h>
#include <openssl/params.h>
#include <openssl/self_test.h>
#include "prov/providercommon.h"
#include "prov/provider_ctx.h"
#include "internal/cryptlib.h"
#include "crypto/rand_pool.h"
#include "drbg_local.h"
#include "prov/seeding.h"
#include "crypto/context.h"

typedef struct crng_test_global_st {
    unsigned char crngt_prev[EVP_MAX_MD_SIZE];
    EVP_MD *md;
    int preloaded;
    CRYPTO_RWLOCK *lock;
} CRNG_TEST_GLOBAL;

static int crngt_get_entropy(PROV_CTX *provctx, const EVP_MD *digest,
                             unsigned char *buf, unsigned char *md,
                             unsigned int *md_size)
{
    int r;
    size_t n;
    unsigned char *p;

    n = ossl_prov_get_entropy(provctx, &p, 0, CRNGT_BUFSIZ, CRNGT_BUFSIZ);
    if (n == CRNGT_BUFSIZ) {
        r = EVP_Digest(p, CRNGT_BUFSIZ, md, md_size, digest, NULL);
        if (r != 0)
            memcpy(buf, p, CRNGT_BUFSIZ);
        ossl_prov_cleanup_entropy(provctx, p, n);
        return r != 0;
    }
    if (n != 0)
        ossl_prov_cleanup_entropy(provctx, p, n);
    return 0;
}

void ossl_rand_crng_ctx_free(void *vcrngt_glob)
{
    CRNG_TEST_GLOBAL *crngt_glob = vcrngt_glob;

    CRYPTO_THREAD_lock_free(crngt_glob->lock);
    EVP_MD_free(crngt_glob->md);
    OPENSSL_free(crngt_glob);
}

void *ossl_rand_crng_ctx_new(OSSL_LIB_CTX *ctx)
{
    CRNG_TEST_GLOBAL *crngt_glob = OPENSSL_zalloc(sizeof(*crngt_glob));

    if (crngt_glob == NULL)
        return NULL;

    if ((crngt_glob->md = EVP_MD_fetch(ctx, "SHA256", "")) == NULL) {
        OPENSSL_free(crngt_glob);
        return NULL;
    }

    if ((crngt_glob->lock = CRYPTO_THREAD_lock_new()) == NULL) {
        EVP_MD_free(crngt_glob->md);
        OPENSSL_free(crngt_glob);
        return NULL;
    }

    return crngt_glob;
}

static int prov_crngt_compare_previous(const unsigned char *prev,
                                       const unsigned char *cur,
                                       size_t sz)
{
    const int res = memcmp(prev, cur, sz) != 0;

    if (!res)
        ossl_set_error_state(OSSL_SELF_TEST_TYPE_CRNG);
    return res;
}

size_t ossl_crngt_get_entropy(PROV_DRBG *drbg,
                              unsigned char **pout,
                              int entropy, size_t min_len, size_t max_len,
                              int prediction_resistance)
{
    unsigned char md[EVP_MAX_MD_SIZE];
    unsigned char buf[CRNGT_BUFSIZ];
    unsigned char *ent, *entp, *entbuf;
    unsigned int sz;
    size_t bytes_needed;
    size_t r = 0, s, t;
    int crng_test_pass = 1;
    OSSL_LIB_CTX *libctx = ossl_prov_ctx_get0_libctx(drbg->provctx);
    CRNG_TEST_GLOBAL *crngt_glob
        = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_RAND_CRNGT_INDEX);
    OSSL_CALLBACK *stcb = NULL;
    void *stcbarg = NULL;
    OSSL_SELF_TEST *st = NULL;

    if (crngt_glob == NULL)
        return 0;

    if (!CRYPTO_THREAD_write_lock(crngt_glob->lock))
        return 0;

    if (!crngt_glob->preloaded) {
        if (!crngt_get_entropy(drbg->provctx, crngt_glob->md, buf,
                               crngt_glob->crngt_prev, NULL)) {
            OPENSSL_cleanse(buf, sizeof(buf));
            goto unlock_return;
        }
        crngt_glob->preloaded = 1;
    }

    /*
     * Calculate how many bytes of seed material we require, rounded up
     * to the nearest byte.  If the entropy is of less than full quality,
     * the amount required should be scaled up appropriately here.
     */
    bytes_needed = (entropy + 7) / 8;
    if (bytes_needed < min_len)
        bytes_needed = min_len;
    if (bytes_needed > max_len)
        goto unlock_return;
    entp = ent = OPENSSL_secure_malloc(bytes_needed);
    if (ent == NULL)
        goto unlock_return;

    OSSL_SELF_TEST_get_callback(libctx, &stcb, &stcbarg);
    if (stcb != NULL) {
        st = OSSL_SELF_TEST_new(stcb, stcbarg);
        if (st == NULL)
            goto err;
        OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_CRNG,
                               OSSL_SELF_TEST_DESC_RNG);
    }

    for (t = bytes_needed; t > 0;) {
        /* Care needs to be taken to avoid overrunning the buffer */
        s = t >= CRNGT_BUFSIZ ? CRNGT_BUFSIZ : t;
        entbuf = t >= CRNGT_BUFSIZ ? entp : buf;
        if (!crngt_get_entropy(drbg->provctx, crngt_glob->md, entbuf, md, &sz))
            goto err;
        if (t < CRNGT_BUFSIZ)
            memcpy(entp, buf, t);
        /* Force a failure here if the callback returns 1 */
        if (OSSL_SELF_TEST_oncorrupt_byte(st, md))
            memcpy(md, crngt_glob->crngt_prev, sz);
        if (!prov_crngt_compare_previous(crngt_glob->crngt_prev, md, sz)) {
            crng_test_pass = 0;
            goto err;
        }
        /* Update for next block */
        memcpy(crngt_glob->crngt_prev, md, sz);
        entp += s;
        t -= s;
    }
    r = bytes_needed;
    *pout = ent;
    ent = NULL;

 err:
    OSSL_SELF_TEST_onend(st, crng_test_pass);
    OSSL_SELF_TEST_free(st);
    OPENSSL_secure_clear_free(ent, bytes_needed);

 unlock_return:
    CRYPTO_THREAD_unlock(crngt_glob->lock);
    return r;
}

void ossl_crngt_cleanup_entropy(ossl_unused PROV_DRBG *drbg,
                                unsigned char *out, size_t outlen)
{
    OPENSSL_secure_clear_free(out, outlen);
}
