Commit 9632bd0e authored by Matt Caswell's avatar Matt Caswell
Browse files

Convert bn_rand.c to use EVP



Replace the low level SHA512_* function calls with EVP calls.

Reviewed-by: default avatarRichard Levitte <levitte@openssl.org>
Reviewed-by: default avatarShane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9130)
parent 7bc081dd
Loading
Loading
Loading
Loading
+27 −9
Original line number Diff line number Diff line
@@ -12,7 +12,9 @@
#include "internal/cryptlib.h"
#include "bn_lcl.h"
#include <openssl/rand.h>
#include <openssl/rand_drbg.h>
#include <openssl/sha.h>
#include <openssl/evp.h>

typedef enum bnrand_flag_e {
    NORMAL, TESTING, PRIVATE
@@ -206,7 +208,7 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range,
                          const BIGNUM *priv, const unsigned char *message,
                          size_t message_len, BN_CTX *ctx)
{
    SHA512_CTX sha;
    EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
    /*
     * We use 512 bits of random data per iteration to ensure that we have at
     * least |range| bits of randomness.
@@ -217,8 +219,14 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range,
    /* We generate |range|+8 bytes of random output. */
    const unsigned num_k_bytes = BN_num_bytes(range) + 8;
    unsigned char private_bytes[96];
    unsigned char *k_bytes;
    unsigned char *k_bytes = NULL;
    int ret = 0;
    EVP_MD *md = NULL;
    OPENSSL_CTX *libctx = (ctx != NULL) ? bn_get_lib_ctx(ctx) : NULL;
    RAND_DRBG *privdrbg = OPENSSL_CTX_get0_private_drbg(libctx);

    if (mdctx == NULL || privdrbg == NULL)
        goto err;

    k_bytes = OPENSSL_malloc(num_k_bytes);
    if (k_bytes == NULL)
@@ -238,15 +246,23 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range,
    memcpy(private_bytes, priv->d, todo);
    memset(private_bytes + todo, 0, sizeof(private_bytes) - todo);

    md = EVP_MD_fetch(libctx, "SHA512", NULL);
    if (md == NULL) {
        BNerr(BN_F_BN_GENERATE_DSA_NONCE, BN_R_NO_SUITABLE_DIGEST);
        goto err;
    }
    for (done = 0; done < num_k_bytes;) {
        if (RAND_priv_bytes(random_bytes, sizeof(random_bytes)) != 1)
        if (!RAND_DRBG_bytes(privdrbg, random_bytes, sizeof(random_bytes)))
            goto err;

        if (!EVP_DigestInit_ex(mdctx, md, NULL)
                || !EVP_DigestUpdate(mdctx, &done, sizeof(done))
                || !EVP_DigestUpdate(mdctx, private_bytes,
                                     sizeof(private_bytes))
                || !EVP_DigestUpdate(mdctx, message, message_len)
                || !EVP_DigestUpdate(mdctx, random_bytes, sizeof(random_bytes))
                || !EVP_DigestFinal_ex(mdctx, digest, NULL))
            goto err;
        SHA512_Init(&sha);
        SHA512_Update(&sha, &done, sizeof(done));
        SHA512_Update(&sha, private_bytes, sizeof(private_bytes));
        SHA512_Update(&sha, message, message_len);
        SHA512_Update(&sha, random_bytes, sizeof(random_bytes));
        SHA512_Final(digest, &sha);

        todo = num_k_bytes - done;
        if (todo > SHA512_DIGEST_LENGTH)
@@ -262,6 +278,8 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range,
    ret = 1;

 err:
    EVP_MD_CTX_free(mdctx);
    EVP_MD_meth_free(md);
    OPENSSL_free(k_bytes);
    OPENSSL_cleanse(private_bytes, sizeof(private_bytes));
    return ret;