Blame crypto/rand/drbg_selftest.c

Packit c4476c
/*
Packit c4476c
 * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
Packit c4476c
 *
Packit c4476c
 * Licensed under the OpenSSL license (the "License").  You may not use
Packit c4476c
 * this file except in compliance with the License.  You can obtain a copy
Packit c4476c
 * in the file LICENSE in the source distribution or at
Packit c4476c
 * https://www.openssl.org/source/license.html
Packit c4476c
 */
Packit c4476c
Packit c4476c
#include <string.h>
Packit c4476c
#include <stddef.h>
Packit c4476c
#include "internal/nelem.h"
Packit c4476c
#include <openssl/crypto.h>
Packit c4476c
#include <openssl/err.h>
Packit c4476c
#include <openssl/rand_drbg.h>
Packit c4476c
#include <openssl/obj_mac.h>
Packit c4476c
#include "internal/thread_once.h"
Packit c4476c
#include "crypto/rand.h"
Packit c4476c
Packit c4476c
typedef struct test_ctx_st {
Packit c4476c
    const unsigned char *entropy;
Packit c4476c
    size_t entropylen;
Packit c4476c
    int entropycnt;
Packit c4476c
    const unsigned char *nonce;
Packit c4476c
    size_t noncelen;
Packit c4476c
    int noncecnt;
Packit c4476c
} TEST_CTX;
Packit c4476c
Packit c4476c
static int app_data_index = -1;
Packit c4476c
static CRYPTO_ONCE get_index_once = CRYPTO_ONCE_STATIC_INIT;
Packit c4476c
DEFINE_RUN_ONCE_STATIC(drbg_app_data_index_init)
Packit c4476c
{
Packit c4476c
    app_data_index = RAND_DRBG_get_ex_new_index(0L, NULL, NULL, NULL, NULL);
Packit c4476c
Packit c4476c
    return 1;
Packit c4476c
}
Packit c4476c
Packit c4476c
enum drbg_kat_type {
Packit c4476c
    NO_RESEED,
Packit c4476c
    PR_FALSE,
Packit c4476c
    PR_TRUE
Packit c4476c
};
Packit c4476c
Packit c4476c
enum drbg_df {
Packit c4476c
    USE_DF,
Packit c4476c
    NO_DF,
Packit c4476c
    NA
Packit c4476c
};
Packit c4476c
Packit c4476c
struct drbg_kat_no_reseed {
Packit c4476c
    size_t count;
Packit c4476c
    const unsigned char *entropyin;
Packit c4476c
    const unsigned char *nonce;
Packit c4476c
    const unsigned char *persstr;
Packit c4476c
    const unsigned char *addin1;
Packit c4476c
    const unsigned char *addin2;
Packit c4476c
    const unsigned char *retbytes;
Packit c4476c
};
Packit c4476c
Packit c4476c
struct drbg_kat_pr_false {
Packit c4476c
    size_t count;
Packit c4476c
    const unsigned char *entropyin;
Packit c4476c
    const unsigned char *nonce;
Packit c4476c
    const unsigned char *persstr;
Packit c4476c
    const unsigned char *entropyinreseed;
Packit c4476c
    const unsigned char *addinreseed;
Packit c4476c
    const unsigned char *addin1;
Packit c4476c
    const unsigned char *addin2;
Packit c4476c
    const unsigned char *retbytes;
Packit c4476c
};
Packit c4476c
Packit c4476c
struct drbg_kat_pr_true {
Packit c4476c
    size_t count;
Packit c4476c
    const unsigned char *entropyin;
Packit c4476c
    const unsigned char *nonce;
Packit c4476c
    const unsigned char *persstr;
Packit c4476c
    const unsigned char *entropyinpr1;
Packit c4476c
    const unsigned char *addin1;
Packit c4476c
    const unsigned char *entropyinpr2;
Packit c4476c
    const unsigned char *addin2;
Packit c4476c
    const unsigned char *retbytes;
Packit c4476c
};
Packit c4476c
Packit c4476c
struct drbg_kat {
Packit c4476c
    enum drbg_kat_type type;
Packit c4476c
    enum drbg_df df;
Packit c4476c
    int nid;
Packit c4476c
Packit c4476c
    size_t entropyinlen;
Packit c4476c
    size_t noncelen;
Packit c4476c
    size_t persstrlen;
Packit c4476c
    size_t addinlen;
Packit c4476c
    size_t retbyteslen;
Packit c4476c
Packit c4476c
    const void *t;
Packit c4476c
};
Packit c4476c
Packit c4476c
/*
Packit c4476c
 * Excerpt from test/drbg_cavs_data.c
Packit c4476c
 * DRBG test vectors from:
Packit c4476c
 * https://csrc.nist.gov/projects/cryptographic-algorithm-validation-program/
Packit c4476c
 */
Packit c4476c
Packit c4476c
static const unsigned char kat1308_entropyin[] = {
Packit c4476c
    0x7c, 0x5d, 0x90, 0x70, 0x3b, 0x8a, 0xc7, 0x0f, 0x23, 0x73, 0x24, 0x9c,
Packit c4476c
    0xa7, 0x15, 0x41, 0x71, 0x7a, 0x31, 0xea, 0x32, 0xfc, 0x28, 0x0d, 0xd7,
Packit c4476c
    0x5b, 0x09, 0x01, 0x98, 0x1b, 0xe2, 0xa5, 0x53, 0xd9, 0x05, 0x32, 0x97,
Packit c4476c
    0xec, 0xbe, 0x86, 0xfd, 0x1c, 0x1c, 0x71, 0x4c, 0x52, 0x29, 0x9e, 0x52,
Packit c4476c
};
Packit c4476c
static const unsigned char kat1308_nonce[] = {0};
Packit c4476c
static const unsigned char kat1308_persstr[] = {
Packit c4476c
    0xdc, 0x07, 0x2f, 0x68, 0xfa, 0x77, 0x03, 0x23, 0x42, 0xb0, 0xf5, 0xa2,
Packit c4476c
    0xd9, 0xad, 0xa1, 0xd0, 0xad, 0xa2, 0x14, 0xb4, 0xd0, 0x8e, 0xfb, 0x39,
Packit c4476c
    0xdd, 0xc2, 0xac, 0xfb, 0x98, 0xdf, 0x7f, 0xce, 0x4c, 0x75, 0x56, 0x45,
Packit c4476c
    0xcd, 0x86, 0x93, 0x74, 0x90, 0x6e, 0xf6, 0x9e, 0x85, 0x7e, 0xfb, 0xc3,
Packit c4476c
};
Packit c4476c
static const unsigned char kat1308_addin0[] = {
Packit c4476c
    0x52, 0x25, 0xc4, 0x2f, 0x03, 0xce, 0x29, 0x71, 0xc5, 0x0b, 0xc3, 0x4e,
Packit c4476c
    0xad, 0x8d, 0x6f, 0x17, 0x82, 0xe1, 0xf3, 0xfd, 0xfd, 0x9b, 0x94, 0x9a,
Packit c4476c
    0x1d, 0xac, 0xd0, 0xd4, 0x3f, 0x2b, 0xe3, 0xab, 0x7c, 0x3d, 0x3e, 0x5a,
Packit c4476c
    0x68, 0xbb, 0xa4, 0x74, 0x68, 0x1a, 0xc6, 0x27, 0xff, 0xe0, 0xc0, 0x6c,
Packit c4476c
};
Packit c4476c
static const unsigned char kat1308_addin1[] = {
Packit c4476c
    0xdc, 0x91, 0xd7, 0xb7, 0xb9, 0x94, 0x79, 0x0f, 0x06, 0xc4, 0x70, 0x19,
Packit c4476c
    0x33, 0x25, 0x7c, 0x96, 0x01, 0xa0, 0x62, 0xb0, 0x50, 0xe6, 0xc0, 0x3a,
Packit c4476c
    0x56, 0x8f, 0xc5, 0x50, 0x48, 0xc6, 0xf4, 0x49, 0xe5, 0x70, 0x16, 0x2e,
Packit c4476c
    0xae, 0xf2, 0x99, 0xb4, 0x2d, 0x70, 0x18, 0x16, 0xcd, 0xe0, 0x24, 0xe4,
Packit c4476c
};
Packit c4476c
static const unsigned char kat1308_retbits[] = {
Packit c4476c
    0xde, 0xf8, 0x91, 0x1b, 0xf1, 0xe1, 0xa9, 0x97, 0xd8, 0x61, 0x84, 0xe2,
Packit c4476c
    0xdb, 0x83, 0x3e, 0x60, 0x45, 0xcd, 0xc8, 0x66, 0x93, 0x28, 0xc8, 0x92,
Packit c4476c
    0xbc, 0x25, 0xae, 0xe8, 0xb0, 0xed, 0xed, 0x16, 0x3d, 0xa5, 0xf9, 0x0f,
Packit c4476c
    0xb3, 0x72, 0x08, 0x84, 0xac, 0x3c, 0x3b, 0xaa, 0x5f, 0xf9, 0x7d, 0x63,
Packit c4476c
    0x3e, 0xde, 0x59, 0x37, 0x0e, 0x40, 0x12, 0x2b, 0xbc, 0x6c, 0x96, 0x53,
Packit c4476c
    0x26, 0x32, 0xd0, 0xb8,
Packit c4476c
};
Packit c4476c
static const struct drbg_kat_no_reseed kat1308_t = {
Packit c4476c
    2, kat1308_entropyin, kat1308_nonce, kat1308_persstr,
Packit c4476c
    kat1308_addin0, kat1308_addin1, kat1308_retbits
Packit c4476c
};
Packit c4476c
static const struct drbg_kat kat1308 = {
Packit c4476c
    NO_RESEED, NO_DF, NID_aes_256_ctr, 48, 0, 48, 48, 64, &kat1308_t
Packit c4476c
};
Packit c4476c
Packit c4476c
static const unsigned char kat1465_entropyin[] = {
Packit c4476c
    0xc9, 0x96, 0x3a, 0x15, 0x51, 0x76, 0x4f, 0xe0, 0x45, 0x82, 0x8a, 0x64,
Packit c4476c
    0x87, 0xbe, 0xaa, 0xc0,
Packit c4476c
};
Packit c4476c
static const unsigned char kat1465_nonce[] = {
Packit c4476c
    0x08, 0xcd, 0x69, 0x39, 0xf8, 0x58, 0x9a, 0x85,
Packit c4476c
};
Packit c4476c
static const unsigned char kat1465_persstr[] = {0};
Packit c4476c
static const unsigned char kat1465_entropyinreseed[] = {
Packit c4476c
    0x16, 0xcc, 0x35, 0x15, 0xb1, 0x17, 0xf5, 0x33, 0x80, 0x9a, 0x80, 0xc5,
Packit c4476c
    0x1f, 0x4b, 0x7b, 0x51,
Packit c4476c
};
Packit c4476c
static const unsigned char kat1465_addinreseed[] = {
Packit c4476c
    0xf5, 0x3d, 0xf1, 0x2e, 0xdb, 0x28, 0x1c, 0x00, 0x7b, 0xcb, 0xb6, 0x12,
Packit c4476c
    0x61, 0x9f, 0x26, 0x5f,
Packit c4476c
};
Packit c4476c
static const unsigned char kat1465_addin0[] = {
Packit c4476c
    0xe2, 0x67, 0x06, 0x62, 0x09, 0xa7, 0xcf, 0xd6, 0x84, 0x8c, 0x20, 0xf6,
Packit c4476c
    0x10, 0x5a, 0x73, 0x9c,
Packit c4476c
};
Packit c4476c
static const unsigned char kat1465_addin1[] = {
Packit c4476c
    0x26, 0xfa, 0x50, 0xe1, 0xb3, 0xcb, 0x65, 0xed, 0xbc, 0x6d, 0xda, 0x18,
Packit c4476c
    0x47, 0x99, 0x1f, 0xeb,
Packit c4476c
};
Packit c4476c
static const unsigned char kat1465_retbits[] = {
Packit c4476c
    0xf9, 0x47, 0xc6, 0xb0, 0x58, 0xa8, 0x66, 0x8a, 0xf5, 0x2b, 0x2a, 0x6d,
Packit c4476c
    0x4e, 0x24, 0x6f, 0x65, 0xbf, 0x51, 0x22, 0xbf, 0xe8, 0x8d, 0x6c, 0xeb,
Packit c4476c
    0xf9, 0x68, 0x7f, 0xed, 0x3b, 0xdd, 0x6b, 0xd5, 0x28, 0x47, 0x56, 0x52,
Packit c4476c
    0xda, 0x50, 0xf0, 0x90, 0x73, 0x95, 0x06, 0x58, 0xaf, 0x08, 0x98, 0x6e,
Packit c4476c
    0x24, 0x18, 0xfd, 0x2f, 0x48, 0x72, 0x57, 0xd6, 0x59, 0xab, 0xe9, 0x41,
Packit c4476c
    0x58, 0xdb, 0x27, 0xba,
Packit c4476c
};
Packit c4476c
static const struct drbg_kat_pr_false kat1465_t = {
Packit c4476c
    9, kat1465_entropyin, kat1465_nonce, kat1465_persstr,
Packit c4476c
    kat1465_entropyinreseed, kat1465_addinreseed, kat1465_addin0,
Packit c4476c
    kat1465_addin1, kat1465_retbits
Packit c4476c
};
Packit c4476c
static const struct drbg_kat kat1465 = {
Packit c4476c
    PR_FALSE, USE_DF, NID_aes_128_ctr, 16, 8, 0, 16, 64, &kat1465_t
Packit c4476c
};
Packit c4476c
Packit c4476c
static const unsigned char kat3146_entropyin[] = {
Packit c4476c
    0xd7, 0x08, 0x42, 0x82, 0xc2, 0xd2, 0xd1, 0xde, 0x01, 0xb4, 0x36, 0xb3,
Packit c4476c
    0x7f, 0xbd, 0xd3, 0xdd, 0xb3, 0xc4, 0x31, 0x4f, 0x8f, 0xa7, 0x10, 0xf4,
Packit c4476c
};
Packit c4476c
static const unsigned char kat3146_nonce[] = {
Packit c4476c
    0x7b, 0x9e, 0xcd, 0x49, 0x4f, 0x46, 0xa0, 0x08, 0x32, 0xff, 0x2e, 0xc3,
Packit c4476c
    0x50, 0x86, 0xca, 0xca,
Packit c4476c
};
Packit c4476c
static const unsigned char kat3146_persstr[] = {0};
Packit c4476c
static const unsigned char kat3146_entropyinpr1[] = {
Packit c4476c
    0x68, 0xd0, 0x7b, 0xa4, 0xe7, 0x22, 0x19, 0xe6, 0xb6, 0x46, 0x6a, 0xda,
Packit c4476c
    0x8e, 0x67, 0xea, 0x63, 0x3f, 0xaf, 0x2f, 0x6c, 0x9d, 0x5e, 0x48, 0x15,
Packit c4476c
};
Packit c4476c
static const unsigned char kat3146_addinpr1[] = {
Packit c4476c
    0x70, 0x0f, 0x54, 0xf4, 0x53, 0xde, 0xca, 0x61, 0x5c, 0x49, 0x51, 0xd1,
Packit c4476c
    0x41, 0xc4, 0xf1, 0x2f, 0x65, 0xfb, 0x7e, 0xbc, 0x9b, 0x14, 0xba, 0x90,
Packit c4476c
    0x05, 0x33, 0x7e, 0x64, 0xb7, 0x2b, 0xaf, 0x99,
Packit c4476c
};
Packit c4476c
static const unsigned char kat3146_entropyinpr2[] = {
Packit c4476c
    0xeb, 0x77, 0xb0, 0xe9, 0x2d, 0x31, 0xc8, 0x66, 0xc5, 0xc4, 0xa7, 0xf7,
Packit c4476c
    0x6c, 0xb2, 0x74, 0x36, 0x4b, 0x25, 0x78, 0x04, 0xd8, 0xd7, 0xd2, 0x34,
Packit c4476c
};
Packit c4476c
static const unsigned char kat3146_addinpr2[] = {
Packit c4476c
    0x05, 0xcd, 0x2a, 0x97, 0x5a, 0x5d, 0xfb, 0x98, 0xc1, 0xf1, 0x00, 0x0c,
Packit c4476c
    0xed, 0xe6, 0x2a, 0xba, 0xf0, 0x89, 0x1f, 0x5a, 0x4f, 0xd7, 0x48, 0xb3,
Packit c4476c
    0x24, 0xc0, 0x8a, 0x3d, 0x60, 0x59, 0x5d, 0xb6,
Packit c4476c
};
Packit c4476c
static const unsigned char kat3146_retbits[] = {
Packit c4476c
    0x29, 0x94, 0xa4, 0xa8, 0x17, 0x3e, 0x62, 0x2f, 0x94, 0xdd, 0x40, 0x1f,
Packit c4476c
    0xe3, 0x7e, 0x77, 0xd4, 0x38, 0xbc, 0x0e, 0x49, 0x46, 0xf6, 0x0e, 0x28,
Packit c4476c
    0x91, 0xc6, 0x9c, 0xc4, 0xa6, 0xa1, 0xf8, 0x9a, 0x64, 0x5e, 0x99, 0x76,
Packit c4476c
    0xd0, 0x2d, 0xee, 0xde, 0xe1, 0x2c, 0x93, 0x29, 0x4b, 0x12, 0xcf, 0x87,
Packit c4476c
    0x03, 0x98, 0xb9, 0x74, 0x41, 0xdb, 0x3a, 0x49, 0x9f, 0x92, 0xd0, 0x45,
Packit c4476c
    0xd4, 0x30, 0x73, 0xbb,
Packit c4476c
};
Packit c4476c
static const struct drbg_kat_pr_true kat3146_t = {
Packit c4476c
    10, kat3146_entropyin, kat3146_nonce, kat3146_persstr,
Packit c4476c
    kat3146_entropyinpr1, kat3146_addinpr1, kat3146_entropyinpr2,
Packit c4476c
    kat3146_addinpr2, kat3146_retbits
Packit c4476c
};
Packit c4476c
static const struct drbg_kat kat3146 = {
Packit c4476c
    PR_TRUE, USE_DF, NID_aes_192_ctr, 24, 16, 0, 32, 64, &kat3146_t
Packit c4476c
};
Packit c4476c
Packit c4476c
static const struct drbg_kat *drbg_test[] = { &kat1308, &kat1465, &kat3146 };
Packit c4476c
Packit c4476c
static const size_t drbg_test_nelem = OSSL_NELEM(drbg_test);
Packit c4476c
Packit c4476c
static size_t kat_entropy(RAND_DRBG *drbg, unsigned char **pout,
Packit c4476c
                          int entropy, size_t min_len, size_t max_len,
Packit c4476c
                          int prediction_resistance)
Packit c4476c
{
Packit c4476c
    TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_ex_data(drbg, app_data_index);
Packit c4476c
Packit c4476c
    t->entropycnt++;
Packit c4476c
    *pout = (unsigned char *)t->entropy;
Packit c4476c
    return t->entropylen;
Packit c4476c
}
Packit c4476c
Packit c4476c
static size_t kat_nonce(RAND_DRBG *drbg, unsigned char **pout,
Packit c4476c
                        int entropy, size_t min_len, size_t max_len)
Packit c4476c
{
Packit c4476c
    TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_ex_data(drbg, app_data_index);
Packit c4476c
Packit c4476c
    t->noncecnt++;
Packit c4476c
    *pout = (unsigned char *)t->nonce;
Packit c4476c
    return t->noncelen;
Packit c4476c
}
Packit c4476c
Packit c4476c
/*
Packit c4476c
 * Do a single NO_RESEED KAT:
Packit c4476c
 *
Packit c4476c
 * Instantiate
Packit c4476c
 * Generate Random Bits (pr=false)
Packit c4476c
 * Generate Random Bits (pr=false)
Packit c4476c
 * Uninstantiate
Packit c4476c
 *
Packit c4476c
 * Return 0 on failure.
Packit c4476c
 */
Packit c4476c
static int single_kat_no_reseed(const struct drbg_kat *td)
Packit c4476c
{
Packit c4476c
    struct drbg_kat_no_reseed *data = (struct drbg_kat_no_reseed *)td->t;
Packit c4476c
    RAND_DRBG *drbg = NULL;
Packit c4476c
    unsigned char *buff = NULL;
Packit c4476c
    unsigned int flags = 0;
Packit c4476c
    int failures = 0;
Packit c4476c
    TEST_CTX t;
Packit c4476c
Packit c4476c
    if (td->df != USE_DF)
Packit c4476c
        flags |= RAND_DRBG_FLAG_CTR_NO_DF;
Packit c4476c
Packit c4476c
    if ((drbg = RAND_DRBG_new(td->nid, flags, NULL)) == NULL)
Packit c4476c
        return 0;
Packit c4476c
Packit c4476c
    if (!RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL,
Packit c4476c
                                 kat_nonce, NULL)) {
Packit c4476c
        failures++;
Packit c4476c
        goto err;
Packit c4476c
    }
Packit c4476c
    memset(&t, 0, sizeof(t));
Packit c4476c
    t.entropy = data->entropyin;
Packit c4476c
    t.entropylen = td->entropyinlen;
Packit c4476c
    t.nonce = data->nonce;
Packit c4476c
    t.noncelen = td->noncelen;
Packit c4476c
    RAND_DRBG_set_ex_data(drbg, app_data_index, &t);
Packit c4476c
Packit c4476c
    buff = OPENSSL_malloc(td->retbyteslen);
Packit c4476c
    if (buff == NULL) {
Packit c4476c
        failures++;
Packit c4476c
        goto err;
Packit c4476c
    }
Packit c4476c
Packit c4476c
    if (!RAND_DRBG_instantiate(drbg, data->persstr, td->persstrlen)
Packit c4476c
        || !RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0,
Packit c4476c
                               data->addin1, td->addinlen)
Packit c4476c
        || !RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0,
Packit c4476c
                               data->addin2, td->addinlen)
Packit c4476c
        || memcmp(data->retbytes, buff,
Packit c4476c
                  td->retbyteslen) != 0)
Packit c4476c
        failures++;
Packit c4476c
Packit c4476c
err:
Packit c4476c
    OPENSSL_free(buff);
Packit c4476c
    RAND_DRBG_uninstantiate(drbg);
Packit c4476c
    RAND_DRBG_free(drbg);
Packit c4476c
    return failures == 0;
Packit c4476c
}
Packit c4476c
Packit c4476c
/*-
Packit c4476c
 * Do a single PR_FALSE KAT:
Packit c4476c
 *
Packit c4476c
 * Instantiate
Packit c4476c
 * Reseed
Packit c4476c
 * Generate Random Bits (pr=false)
Packit c4476c
 * Generate Random Bits (pr=false)
Packit c4476c
 * Uninstantiate
Packit c4476c
 *
Packit c4476c
 * Return 0 on failure.
Packit c4476c
 */
Packit c4476c
static int single_kat_pr_false(const struct drbg_kat *td)
Packit c4476c
{
Packit c4476c
    struct drbg_kat_pr_false *data = (struct drbg_kat_pr_false *)td->t;
Packit c4476c
    RAND_DRBG *drbg = NULL;
Packit c4476c
    unsigned char *buff = NULL;
Packit c4476c
    unsigned int flags = 0;
Packit c4476c
    int failures = 0;
Packit c4476c
    TEST_CTX t;
Packit c4476c
Packit c4476c
    if (td->df != USE_DF)
Packit c4476c
        flags |= RAND_DRBG_FLAG_CTR_NO_DF;
Packit c4476c
Packit c4476c
    if ((drbg = RAND_DRBG_new(td->nid, flags, NULL)) == NULL)
Packit c4476c
        return 0;
Packit c4476c
Packit c4476c
    if (!RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL,
Packit c4476c
                                 kat_nonce, NULL)) {
Packit c4476c
        failures++;
Packit c4476c
        goto err;
Packit c4476c
    }
Packit c4476c
    memset(&t, 0, sizeof(t));
Packit c4476c
    t.entropy = data->entropyin;
Packit c4476c
    t.entropylen = td->entropyinlen;
Packit c4476c
    t.nonce = data->nonce;
Packit c4476c
    t.noncelen = td->noncelen;
Packit c4476c
    RAND_DRBG_set_ex_data(drbg, app_data_index, &t);
Packit c4476c
Packit c4476c
    buff = OPENSSL_malloc(td->retbyteslen);
Packit c4476c
    if (buff == NULL) {
Packit c4476c
        failures++;
Packit c4476c
        goto err;
Packit c4476c
    }
Packit c4476c
Packit c4476c
    if (!RAND_DRBG_instantiate(drbg, data->persstr, td->persstrlen))
Packit c4476c
        failures++;
Packit c4476c
Packit c4476c
    t.entropy = data->entropyinreseed;
Packit c4476c
    t.entropylen = td->entropyinlen;
Packit c4476c
Packit c4476c
    if (!RAND_DRBG_reseed(drbg, data->addinreseed, td->addinlen, 0)
Packit c4476c
        || !RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0,
Packit c4476c
                               data->addin1, td->addinlen)
Packit c4476c
        || !RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0,
Packit c4476c
                               data->addin2, td->addinlen)
Packit c4476c
        || memcmp(data->retbytes, buff,
Packit c4476c
                  td->retbyteslen) != 0)
Packit c4476c
        failures++;
Packit c4476c
Packit c4476c
err:
Packit c4476c
    OPENSSL_free(buff);
Packit c4476c
    RAND_DRBG_uninstantiate(drbg);
Packit c4476c
    RAND_DRBG_free(drbg);
Packit c4476c
    return failures == 0;
Packit c4476c
}
Packit c4476c
Packit c4476c
/*-
Packit c4476c
 * Do a single PR_TRUE KAT:
Packit c4476c
 *
Packit c4476c
 * Instantiate
Packit c4476c
 * Generate Random Bits (pr=true)
Packit c4476c
 * Generate Random Bits (pr=true)
Packit c4476c
 * Uninstantiate
Packit c4476c
 *
Packit c4476c
 * Return 0 on failure.
Packit c4476c
 */
Packit c4476c
static int single_kat_pr_true(const struct drbg_kat *td)
Packit c4476c
{
Packit c4476c
    struct drbg_kat_pr_true *data = (struct drbg_kat_pr_true *)td->t;
Packit c4476c
    RAND_DRBG *drbg = NULL;
Packit c4476c
    unsigned char *buff = NULL;
Packit c4476c
    unsigned int flags = 0;
Packit c4476c
    int failures = 0;
Packit c4476c
    TEST_CTX t;
Packit c4476c
Packit c4476c
    if (td->df != USE_DF)
Packit c4476c
        flags |= RAND_DRBG_FLAG_CTR_NO_DF;
Packit c4476c
Packit c4476c
    if ((drbg = RAND_DRBG_new(td->nid, flags, NULL)) == NULL)
Packit c4476c
        return 0;
Packit c4476c
Packit c4476c
    if (!RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL,
Packit c4476c
                                 kat_nonce, NULL)) {
Packit c4476c
        failures++;
Packit c4476c
        goto err;
Packit c4476c
    }
Packit c4476c
    memset(&t, 0, sizeof(t));
Packit c4476c
    t.nonce = data->nonce;
Packit c4476c
    t.noncelen = td->noncelen;
Packit c4476c
    t.entropy = data->entropyin;
Packit c4476c
    t.entropylen = td->entropyinlen;
Packit c4476c
    RAND_DRBG_set_ex_data(drbg, app_data_index, &t);
Packit c4476c
Packit c4476c
    buff = OPENSSL_malloc(td->retbyteslen);
Packit c4476c
    if (buff == NULL) {
Packit c4476c
        failures++;
Packit c4476c
        goto err;
Packit c4476c
    }
Packit c4476c
Packit c4476c
    if (!RAND_DRBG_instantiate(drbg, data->persstr, td->persstrlen))
Packit c4476c
        failures++;
Packit c4476c
Packit c4476c
    t.entropy = data->entropyinpr1;
Packit c4476c
    t.entropylen = td->entropyinlen;
Packit c4476c
Packit c4476c
    if (!RAND_DRBG_generate(drbg, buff, td->retbyteslen, 1,
Packit c4476c
                            data->addin1, td->addinlen))
Packit c4476c
        failures++;
Packit c4476c
Packit c4476c
    t.entropy = data->entropyinpr2;
Packit c4476c
    t.entropylen = td->entropyinlen;
Packit c4476c
Packit c4476c
    if (!RAND_DRBG_generate(drbg, buff, td->retbyteslen, 1,
Packit c4476c
                            data->addin2, td->addinlen)
Packit c4476c
        || memcmp(data->retbytes, buff,
Packit c4476c
                  td->retbyteslen) != 0)
Packit c4476c
        failures++;
Packit c4476c
Packit c4476c
err:
Packit c4476c
    OPENSSL_free(buff);
Packit c4476c
    RAND_DRBG_uninstantiate(drbg);
Packit c4476c
    RAND_DRBG_free(drbg);
Packit c4476c
    return failures == 0;
Packit c4476c
}
Packit c4476c
Packit c4476c
static int test_kats(int i)
Packit c4476c
{
Packit c4476c
    const struct drbg_kat *td = drbg_test[i];
Packit c4476c
    int rv = 0;
Packit c4476c
Packit c4476c
    switch (td->type) {
Packit c4476c
    case NO_RESEED:
Packit c4476c
        if (!single_kat_no_reseed(td))
Packit c4476c
            goto err;
Packit c4476c
        break;
Packit c4476c
    case PR_FALSE:
Packit c4476c
        if (!single_kat_pr_false(td))
Packit c4476c
            goto err;
Packit c4476c
        break;
Packit c4476c
    case PR_TRUE:
Packit c4476c
        if (!single_kat_pr_true(td))
Packit c4476c
            goto err;
Packit c4476c
        break;
Packit c4476c
    default:	/* cant happen */
Packit c4476c
        goto err;
Packit c4476c
    }
Packit c4476c
    rv = 1;
Packit c4476c
err:
Packit c4476c
    return rv;
Packit c4476c
}
Packit c4476c
Packit c4476c
/*-
Packit c4476c
 * Do one expected-error test:
Packit c4476c
 *
Packit c4476c
 * Instantiate with no entropy supplied
Packit c4476c
 *
Packit c4476c
 * Return 0 on failure.
Packit c4476c
 */
Packit c4476c
static int test_drbg_sanity(const struct drbg_kat *td)
Packit c4476c
{
Packit c4476c
    struct drbg_kat_pr_false *data = (struct drbg_kat_pr_false *)td->t;
Packit c4476c
    RAND_DRBG *drbg = NULL;
Packit c4476c
    unsigned int flags = 0;
Packit c4476c
    int failures = 0;
Packit c4476c
    TEST_CTX t;
Packit c4476c
Packit c4476c
    if (td->df != USE_DF)
Packit c4476c
        flags |= RAND_DRBG_FLAG_CTR_NO_DF;
Packit c4476c
Packit c4476c
    if ((drbg = RAND_DRBG_new(td->nid, flags, NULL)) == NULL)
Packit c4476c
        return 0;
Packit c4476c
Packit c4476c
    if (!RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL,
Packit c4476c
                                 kat_nonce, NULL)) {
Packit c4476c
        failures++;
Packit c4476c
        goto err;
Packit c4476c
    }
Packit c4476c
    memset(&t, 0, sizeof(t));
Packit c4476c
    t.entropy = data->entropyin;
Packit c4476c
    t.entropylen = 0;     /* No entropy */
Packit c4476c
    t.nonce = data->nonce;
Packit c4476c
    t.noncelen = td->noncelen;
Packit c4476c
    RAND_DRBG_set_ex_data(drbg, app_data_index, &t);
Packit c4476c
Packit c4476c
    ERR_set_mark();
Packit c4476c
    /* This must fail. */
Packit c4476c
    if (RAND_DRBG_instantiate(drbg, data->persstr, td->persstrlen))
Packit c4476c
        failures++;
Packit c4476c
    RAND_DRBG_uninstantiate(drbg);
Packit c4476c
    ERR_pop_to_mark();
Packit c4476c
Packit c4476c
err:
Packit c4476c
    RAND_DRBG_free(drbg);
Packit c4476c
    return failures == 0;
Packit c4476c
}
Packit c4476c
Packit c4476c
Packit c4476c
int rand_drbg_selftest(void)
Packit c4476c
{
Packit c4476c
    int i;
Packit c4476c
Packit c4476c
    if (!RUN_ONCE(&get_index_once, drbg_app_data_index_init))
Packit c4476c
        return 0;
Packit c4476c
Packit c4476c
    for (i = 0; i < drbg_test_nelem; i++) {
Packit c4476c
        if (test_kats(i) <= 0)
Packit c4476c
            return 0;
Packit c4476c
    }
Packit c4476c
Packit c4476c
    if (test_drbg_sanity(&kat1465) <= 0)
Packit c4476c
        return 0;
Packit c4476c
Packit c4476c
    return 1;
Packit c4476c
}