Blame crypto/rand/drbg_selftest.c

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