|
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 "internal/nelem.h"
|
|
Packit |
c4476c |
#include <openssl/crypto.h>
|
|
Packit |
c4476c |
#include <openssl/err.h>
|
|
Packit |
c4476c |
#include <openssl/rand.h>
|
|
Packit |
c4476c |
#include <openssl/obj_mac.h>
|
|
Packit |
c4476c |
#include <openssl/evp.h>
|
|
Packit |
c4476c |
#include <openssl/aes.h>
|
|
Packit |
c4476c |
#include "../crypto/rand/rand_local.h"
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
#include "testutil.h"
|
|
Packit |
c4476c |
#include "drbg_cavs_data.h"
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
static int app_data_index;
|
|
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 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 (!TEST_ptr(drbg = RAND_DRBG_new(td->nid, flags, NULL)))
|
|
Packit |
c4476c |
return 0;
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
if (!TEST_true(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 |
goto err;
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
if (!TEST_true(RAND_DRBG_instantiate(drbg, data->persstr, td->persstrlen))
|
|
Packit |
c4476c |
|| !TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0,
|
|
Packit |
c4476c |
data->addin1, td->addinlen))
|
|
Packit |
c4476c |
|| !TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0,
|
|
Packit |
c4476c |
data->addin2, td->addinlen))
|
|
Packit |
c4476c |
|| !TEST_true(RAND_DRBG_uninstantiate(drbg))
|
|
Packit |
c4476c |
|| !TEST_mem_eq(data->retbytes, td->retbyteslen, buff,
|
|
Packit |
c4476c |
td->retbyteslen))
|
|
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 (!TEST_ptr(drbg = RAND_DRBG_new(td->nid, flags, NULL)))
|
|
Packit |
c4476c |
return 0;
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
if (!TEST_true(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 |
goto err;
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
if (!TEST_true(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 (!TEST_true(RAND_DRBG_reseed(drbg, data->addinreseed, td->addinlen, 0))
|
|
Packit |
c4476c |
|| !TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0,
|
|
Packit |
c4476c |
data->addin1, td->addinlen))
|
|
Packit |
c4476c |
|| !TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0,
|
|
Packit |
c4476c |
data->addin2, td->addinlen))
|
|
Packit |
c4476c |
|| !TEST_true(RAND_DRBG_uninstantiate(drbg))
|
|
Packit |
c4476c |
|| !TEST_mem_eq(data->retbytes, td->retbyteslen, buff,
|
|
Packit |
c4476c |
td->retbyteslen))
|
|
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 (!TEST_ptr(drbg = RAND_DRBG_new(td->nid, flags, NULL)))
|
|
Packit |
c4476c |
return 0;
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
if (!TEST_true(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 |
goto err;
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
if (!TEST_true(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 (!TEST_true(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 (!TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 1,
|
|
Packit |
c4476c |
data->addin2, td->addinlen))
|
|
Packit |
c4476c |
|| !TEST_true(RAND_DRBG_uninstantiate(drbg))
|
|
Packit |
c4476c |
|| !TEST_mem_eq(data->retbytes, td->retbyteslen, buff,
|
|
Packit |
c4476c |
td->retbyteslen))
|
|
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_cavs_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 |
int setup_tests(void)
|
|
Packit |
c4476c |
{
|
|
Packit |
c4476c |
app_data_index = RAND_DRBG_get_ex_new_index(0L, NULL, NULL, NULL, NULL);
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
ADD_ALL_TESTS(test_cavs_kats, drbg_test_nelem);
|
|
Packit |
c4476c |
return 1;
|
|
Packit |
c4476c |
}
|