/*
* Copyright 2011-2019 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (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
*/
#include <string.h>
#include "internal/nelem.h"
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/obj_mac.h>
#include <openssl/evp.h>
#include <openssl/aes.h>
#include "../crypto/rand/rand_lcl.h"
#include "../crypto/include/internal/rand_int.h"
#if defined(_WIN32)
# include <windows.h>
#endif
#include "testutil.h"
#include "drbgtest.h"
typedef struct drbg_selftest_data_st {
int post;
int nid;
unsigned int flags;
/* KAT data for no PR */
const unsigned char *entropy;
size_t entropylen;
const unsigned char *nonce;
size_t noncelen;
const unsigned char *pers;
size_t perslen;
const unsigned char *adin;
size_t adinlen;
const unsigned char *entropyreseed;
size_t entropyreseedlen;
const unsigned char *adinreseed;
size_t adinreseedlen;
const unsigned char *adin2;
size_t adin2len;
const unsigned char *expected;
size_t exlen;
const unsigned char *kat2;
size_t kat2len;
/* KAT data for PR */
const unsigned char *entropy_pr;
size_t entropylen_pr;
const unsigned char *nonce_pr;
size_t noncelen_pr;
const unsigned char *pers_pr;
size_t perslen_pr;
const unsigned char *adin_pr;
size_t adinlen_pr;
const unsigned char *entropypr_pr;
size_t entropyprlen_pr;
const unsigned char *ading_pr;
size_t adinglen_pr;
const unsigned char *entropyg_pr;
size_t entropyglen_pr;
const unsigned char *kat_pr;
size_t katlen_pr;
const unsigned char *kat2_pr;
size_t kat2len_pr;
} DRBG_SELFTEST_DATA;
#define make_drbg_test_data(nid, flag, pr, post) {\
post, nid, flag, \
pr##_entropyinput, sizeof(pr##_entropyinput), \
pr##_nonce, sizeof(pr##_nonce), \
pr##_personalizationstring, sizeof(pr##_personalizationstring), \
pr##_additionalinput, sizeof(pr##_additionalinput), \
pr##_entropyinputreseed, sizeof(pr##_entropyinputreseed), \
pr##_additionalinputreseed, sizeof(pr##_additionalinputreseed), \
pr##_additionalinput2, sizeof(pr##_additionalinput2), \
pr##_int_returnedbits, sizeof(pr##_int_returnedbits), \
pr##_returnedbits, sizeof(pr##_returnedbits), \
pr##_pr_entropyinput, sizeof(pr##_pr_entropyinput), \
pr##_pr_nonce, sizeof(pr##_pr_nonce), \
pr##_pr_personalizationstring, sizeof(pr##_pr_personalizationstring), \
pr##_pr_additionalinput, sizeof(pr##_pr_additionalinput), \
pr##_pr_entropyinputpr, sizeof(pr##_pr_entropyinputpr), \
pr##_pr_additionalinput2, sizeof(pr##_pr_additionalinput2), \
pr##_pr_entropyinputpr2, sizeof(pr##_pr_entropyinputpr2), \
pr##_pr_int_returnedbits, sizeof(pr##_pr_int_returnedbits), \
pr##_pr_returnedbits, sizeof(pr##_pr_returnedbits) \
}
#define make_drbg_test_data_use_df(nid, pr, p) \
make_drbg_test_data(nid, 0, pr, p)
#define make_drbg_test_data_no_df(nid, pr, p) \
make_drbg_test_data(nid, RAND_DRBG_FLAG_CTR_NO_DF, pr, p)
static DRBG_SELFTEST_DATA drbg_test[] = {
make_drbg_test_data_no_df (NID_aes_128_ctr, aes_128_no_df, 0),
make_drbg_test_data_no_df (NID_aes_192_ctr, aes_192_no_df, 0),
make_drbg_test_data_no_df (NID_aes_256_ctr, aes_256_no_df, 1),
make_drbg_test_data_use_df(NID_aes_128_ctr, aes_128_use_df, 0),
make_drbg_test_data_use_df(NID_aes_192_ctr, aes_192_use_df, 0),
make_drbg_test_data_use_df(NID_aes_256_ctr, aes_256_use_df, 1),
};
static int app_data_index;
/*
* Test context data, attached as EXDATA to the RAND_DRBG
*/
typedef struct test_ctx_st {
const unsigned char *entropy;
size_t entropylen;
int entropycnt;
const unsigned char *nonce;
size_t noncelen;
int noncecnt;
} TEST_CTX;
static size_t kat_entropy(RAND_DRBG *drbg, unsigned char **pout,
int entropy, size_t min_len, size_t max_len,
int prediction_resistance)
{
TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_ex_data(drbg, app_data_index);
t->entropycnt++;
*pout = (unsigned char *)t->entropy;
return t->entropylen;
}
static size_t kat_nonce(RAND_DRBG *drbg, unsigned char **pout,
int entropy, size_t min_len, size_t max_len)
{
TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_ex_data(drbg, app_data_index);
t->noncecnt++;
*pout = (unsigned char *)t->nonce;
return t->noncelen;
}
static int uninstantiate(RAND_DRBG *drbg)
{
int ret = drbg == NULL ? 1 :