aes ctr_drbg: add cavs tests

Signed-off-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Reviewed-by: Kurt Roeckx <kurt@roeckx.be>
Reviewed-by: Rich Salz <rsalz@openssl.org>
GH: #5580
This commit is contained in:
Patrick Steuer 2018-03-10 19:06:43 +01:00 committed by Kurt Roeckx
parent dbdcc04f27
commit e613b1eff4
5 changed files with 170696 additions and 1 deletions

View file

@ -47,6 +47,7 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN
asn1_encode_test asn1_string_table_test \
x509_time_test x509_dup_cert_test x509_check_cert_pkey_test \
recordlentest drbgtest sslbuffertest \
recordlentest drbgtest drbg_cavs_test sslbuffertest \
time_offset_test pemtest ssl_cert_table_internal_test ciphername_test \
servername_test ocspapitest rsa_mp_test fatalerrtest tls13ccstest \
sysdefaulttest
@ -339,6 +340,10 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN
INCLUDE[drbgtest]=../include
DEPEND[drbgtest]=../libcrypto libtestutil.a
SOURCE[drbg_cavs_test]=drbg_cavs_test.c drbg_cavs_data.c
INCLUDE[drbg_cavs_test]=../include . ..
DEPEND[drbg_cavs_test]=../libcrypto libtestutil.a
SOURCE[x509_dup_cert_test]=x509_dup_cert_test.c
INCLUDE[x509_dup_cert_test]=../include
DEPEND[x509_dup_cert_test]=../libcrypto libtestutil.a

170320
test/drbg_cavs_data.c Normal file

File diff suppressed because it is too large Load diff

82
test/drbg_cavs_data.h Normal file
View file

@ -0,0 +1,82 @@
/*
* Copyright 2017 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
*/
/*
* Known answer tests (KAT) for NIST SP800-90A DRBGs.
*/
#include <stddef.h>
#ifndef DRBG_CAVS_DATA_H
# define DRBG_CAVS_DATA_H
enum drbg_kat_type {
NO_RESEED,
PR_FALSE,
PR_TRUE
};
enum drbg_df {
USE_DF,
NO_DF,
NA
};
struct drbg_kat_no_reseed {
size_t count;
const unsigned char *entropyin;
const unsigned char *nonce;
const unsigned char *persstr;
const unsigned char *addin1;
const unsigned char *addin2;
const unsigned char *retbytes;
};
struct drbg_kat_pr_false {
size_t count;
const unsigned char *entropyin;
const unsigned char *nonce;
const unsigned char *persstr;
const unsigned char *entropyinreseed;
const unsigned char *addinreseed;
const unsigned char *addin1;
const unsigned char *addin2;
const unsigned char *retbytes;
};
struct drbg_kat_pr_true {
size_t count;
const unsigned char *entropyin;
const unsigned char *nonce;
const unsigned char *persstr;
const unsigned char *entropyinpr1;
const unsigned char *addin1;
const unsigned char *entropyinpr2;
const unsigned char *addin2;
const unsigned char *retbytes;
};
struct drbg_kat {
enum drbg_kat_type type;
enum drbg_df df;
int nid;
size_t entropyinlen;
size_t noncelen;
size_t persstrlen;
size_t addinlen;
size_t retbyteslen;
const void *t;
};
extern const struct drbg_kat *drbg_test[];
extern const size_t drbg_test_nelem;
#endif

287
test/drbg_cavs_test.c Normal file
View file

@ -0,0 +1,287 @@
/*
* Copyright 2017 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 "testutil.h"
#include "drbg_cavs_data.h"
static int app_data_index;
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;
}
/*
* Do a single NO_RESEED KAT:
*
* Instantiate
* Generate Random Bits (pr=false)
* Generate Random Bits (pr=false)
* Uninstantiate
*
* Return 0 on failure.
*/
static int single_kat_no_reseed(const struct drbg_kat *td)
{
struct drbg_kat_no_reseed *data = (struct drbg_kat_no_reseed *)td->t;
RAND_DRBG *drbg = NULL;
unsigned char *buff = NULL;
unsigned int flags = 0;
int failures = 0;
TEST_CTX t;
if (td->df != USE_DF)
flags |= RAND_DRBG_FLAG_CTR_NO_DF;
if (!TEST_ptr(drbg = RAND_DRBG_new(td->nid, flags, NULL)))
return 0;
if (!TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL,
kat_nonce, NULL))) {
failures++;
goto err;
}
memset(&t, 0, sizeof(t));
t.entropy = data->entropyin;
t.entropylen = td->entropyinlen;
t.nonce = data->nonce;
t.noncelen = td->noncelen;
RAND_DRBG_set_ex_data(drbg, app_data_index, &t);
buff = OPENSSL_malloc(td->retbyteslen);
if (buff == NULL)
goto err;
if (!TEST_true(RAND_DRBG_instantiate(drbg, data->persstr, td->persstrlen))
|| !TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0,
data->addin1, td->addinlen))
|| !TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0,
data->addin2, td->addinlen))
|| !TEST_true(RAND_DRBG_uninstantiate(drbg))
|| !TEST_mem_eq(data->retbytes, td->retbyteslen, buff,
td->retbyteslen))
failures++;
err:
if (buff != NULL)
OPENSSL_free(buff);
if (drbg != NULL) {
RAND_DRBG_uninstantiate(drbg);
RAND_DRBG_free(drbg);
}
return failures == 0;
}
/*-
* Do a single PR_FALSE KAT:
*
* Instantiate
* Reseed
* Generate Random Bits (pr=false)
* Generate Random Bits (pr=false)
* Uninstantiate
*
* Return 0 on failure.
*/
static int single_kat_pr_false(const struct drbg_kat *td)
{
struct drbg_kat_pr_false *data = (struct drbg_kat_pr_false *)td->t;
RAND_DRBG *drbg = NULL;
unsigned char *buff = NULL;
unsigned int flags = 0;
int failures = 0;
TEST_CTX t;
if (td->df != USE_DF)
flags |= RAND_DRBG_FLAG_CTR_NO_DF;
if (!TEST_ptr(drbg = RAND_DRBG_new(td->nid, flags, NULL)))
return 0;
if (!TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL,
kat_nonce, NULL))) {
failures++;
goto err;
}
memset(&t, 0, sizeof(t));
t.entropy = data->entropyin;
t.entropylen = td->entropyinlen;
t.nonce = data->nonce;
t.noncelen = td->noncelen;
RAND_DRBG_set_ex_data(drbg, app_data_index, &t);
buff = OPENSSL_malloc(td->retbyteslen);
if (buff == NULL)
goto err;
if (!TEST_true(RAND_DRBG_instantiate(drbg, data->persstr, td->persstrlen)))
failures++;
t.entropy = data->entropyinreseed;
t.entropylen = td->entropyinlen;
if (!TEST_true(RAND_DRBG_reseed(drbg, data->addinreseed, td->addinlen, 0))
|| !TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0,
data->addin1, td->addinlen))
|| !TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 0,
data->addin2, td->addinlen))
|| !TEST_true(RAND_DRBG_uninstantiate(drbg))
|| !TEST_mem_eq(data->retbytes, td->retbyteslen, buff,
td->retbyteslen))
failures++;
err:
if (buff != NULL)
OPENSSL_free(buff);
if (drbg != NULL) {
RAND_DRBG_uninstantiate(drbg);
RAND_DRBG_free(drbg);
}
return failures == 0;
}
/*-
* Do a single PR_TRUE KAT:
*
* Instantiate
* Generate Random Bits (pr=true)
* Generate Random Bits (pr=true)
* Uninstantiate
*
* Return 0 on failure.
*/
static int single_kat_pr_true(const struct drbg_kat *td)
{
struct drbg_kat_pr_true *data = (struct drbg_kat_pr_true *)td->t;
RAND_DRBG *drbg = NULL;
unsigned char *buff = NULL;
unsigned int flags = 0;
int failures = 0;
TEST_CTX t;
if (td->df != USE_DF)
flags |= RAND_DRBG_FLAG_CTR_NO_DF;
if (!TEST_ptr(drbg = RAND_DRBG_new(td->nid, flags, NULL)))
return 0;
if (!TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL,
kat_nonce, NULL))) {
failures++;
goto err;
}
memset(&t, 0, sizeof(t));
t.nonce = data->nonce;
t.noncelen = td->noncelen;
t.entropy = data->entropyin;
t.entropylen = td->entropyinlen;
RAND_DRBG_set_ex_data(drbg, app_data_index, &t);
buff = OPENSSL_malloc(td->retbyteslen);
if (buff == NULL)
goto err;
if (!TEST_true(RAND_DRBG_instantiate(drbg, data->persstr, td->persstrlen)))
failures++;
t.entropy = data->entropyinpr1;
t.entropylen = td->entropyinlen;
if (!TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 1,
data->addin1, td->addinlen)))
failures++;
t.entropy = data->entropyinpr2;
t.entropylen = td->entropyinlen;
if (!TEST_true(RAND_DRBG_generate(drbg, buff, td->retbyteslen, 1,
data->addin2, td->addinlen))
|| !TEST_true(RAND_DRBG_uninstantiate(drbg))
|| !TEST_mem_eq(data->retbytes, td->retbyteslen, buff,
td->retbyteslen))
failures++;
err:
if (buff != NULL)
OPENSSL_free(buff);
if (drbg != NULL) {
RAND_DRBG_uninstantiate(drbg);
RAND_DRBG_free(drbg);
}
return failures == 0;
}
static int test_cavs_kats(int i)
{
const struct drbg_kat *td = drbg_test[i];
int rv = 0;
switch (td->type) {
case NO_RESEED:
if (!single_kat_no_reseed(td))
goto err;
break;
case PR_FALSE:
if (!single_kat_pr_false(td))
goto err;
break;
case PR_TRUE:
if (!single_kat_pr_true(td))
goto err;
break;
default: /* cant happen */
goto err;
}
rv = 1;
err:
return rv;
}
int setup_tests(void)
{
app_data_index = RAND_DRBG_get_ex_new_index(0L, NULL, NULL, NULL, NULL);
ADD_ALL_TESTS(test_cavs_kats, drbg_test_nelem);
return 1;
}

View file

@ -10,7 +10,8 @@ use strict;
use warnings;
use OpenSSL::Test;
plan tests => 1;
plan tests => 2;
setup("test_rand");
ok(run(test(["drbgtest"])));
ok(run(test(["drbg_cavs_test"])));