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:
parent
dbdcc04f27
commit
e613b1eff4
5 changed files with 170696 additions and 1 deletions
|
@ -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
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
82
test/drbg_cavs_data.h
Normal 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
287
test/drbg_cavs_test.c
Normal 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;
|
||||
}
|
|
@ -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"])));
|
||||
|
|
Loading…
Reference in a new issue