Add FIPS RNG tests.

Submitted by: Steve Marquess
This commit is contained in:
Andy Polyakov 2005-05-07 22:06:40 +00:00
parent 4b27a9feb3
commit 44e9bc81eb
9 changed files with 389 additions and 15 deletions

View file

@ -239,6 +239,14 @@ int FIPS_mode_set(int onoff,const char *path)
goto end;
}
/* Perform RNG KAT before seeding */
if (!FIPS_selftest_rng())
{
fips_selftest_fail = 1;
ret = 0;
goto end;
}
/* automagically seed PRNG if not already seeded */
if(!FIPS_rand_seeded())
{

View file

@ -99,6 +99,7 @@ void ERR_load_FIPS_strings(void);
#define FIPS_F_FIPS_SELFTEST_AES 104
#define FIPS_F_FIPS_SELFTEST_DES 107
#define FIPS_F_FIPS_SELFTEST_DSA 109
#define FIPS_F_FIPS_SELFTEST_RNG 118
#define FIPS_F_FIPS_SELFTEST_RSA 108
#define FIPS_F_FIPS_SELFTEST_SHA1 103
#define FIPS_F_HASH_FINAL 100

View file

@ -82,6 +82,7 @@ static ERR_STRING_DATA FIPS_str_functs[]=
{ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES), "FIPS_selftest_aes"},
{ERR_FUNC(FIPS_F_FIPS_SELFTEST_DES), "FIPS_selftest_des"},
{ERR_FUNC(FIPS_F_FIPS_SELFTEST_DSA), "FIPS_selftest_dsa"},
{ERR_FUNC(FIPS_F_FIPS_SELFTEST_RNG), "FIPS_selftest_rng"},
{ERR_FUNC(FIPS_F_FIPS_SELFTEST_RSA), "FIPS_selftest_rsa"},
{ERR_FUNC(FIPS_F_FIPS_SELFTEST_SHA1), "FIPS_selftest_sha1"},
{ERR_FUNC(FIPS_F_HASH_FINAL), "HASH_FINAL"},

View file

@ -228,19 +228,22 @@ int main(int argc,char **argv)
/* Corrupted KAT tests */
if (!strcmp(argv[1], "aes")) {
FIPS_corrupt_aes();
printf("3. AES encryption/decryption with corrupted KAT...\n");
printf("AES encryption/decryption with corrupted KAT...\n");
} else if (!strcmp(argv[1], "des")) {
FIPS_corrupt_des();
printf("5. DES-ECB encryption/decryption with corrupted KAT...\n");
printf("DES-ECB encryption/decryption with corrupted KAT...\n");
} else if (!strcmp(argv[1], "dsa")) {
FIPS_corrupt_dsa();
printf("6. DSA key generation and signature validation with corrupted KAT...\n");
printf("DSA key generation and signature validation with corrupted KAT...\n");
} else if (!strcmp(argv[1], "rsa")) {
FIPS_corrupt_rsa();
printf("4. RSA key generation and encryption/decryption with corrupted KAT...\n");
printf("RSA key generation and encryption/decryption with corrupted KAT...\n");
} else if (!strcmp(argv[1], "sha1")) {
FIPS_corrupt_sha1();
printf("7. SHA-1 hash with corrupted KAT...\n");
printf("SHA-1 hash with corrupted KAT...\n");
} else if (!strcmp(argv[1], "rng")) {
FIPS_corrupt_rng();
printf("RNG test with corrupted KAT...\n");
} else {
printf("Bad argument \"%s\"\n", argv[1]);
exit(1);

View file

@ -1,8 +1,8 @@
const char * const FIPS_source_hashes[] = {
"HMAC-SHA1(fips.c)= 2f46f538f12228814cfdc8c6b37261258686fc8c",
"HMAC-SHA1(fips.c)= 23f2470208ebbc7daeae50ad7b13e7cd7e269477",
"HMAC-SHA1(fips_err_wrapper.c)= d3e2be316062510312269e98f964cb87e7577898",
"HMAC-SHA1(fips.h)= 564e34c12d6743a9be06d5da74608a71937c872a",
"HMAC-SHA1(fips_err.h)= 32ad0130f639b8f6ff417d3dfda553f5a1d7512d",
"HMAC-SHA1(fips.h)= 87423b80f7635f08fbea23897c64e999166360a2",
"HMAC-SHA1(fips_err.h)= d356c4436362dba2974f767e06c6be1c90dbfe9f",
"HMAC-SHA1(aes/fips_aes_core.c)= b70bbbd675efe0613da0d57055310926a0104d55",
"HMAC-SHA1(aes/asm/fips-ax86-elf.s)= 361df58c4838e55cf0b5fa1427c81c253e551388",
"HMAC-SHA1(aes/fips_aes_selftest.c)= 98b01502221e7fe529fd981222f2cbb52eb4cbe0",
@ -18,8 +18,9 @@ const char * const FIPS_source_hashes[] = {
"HMAC-SHA1(dsa/fips_dsa_ossl.c)= 8bb943c0fd1adf04f6a845f4d1727c5472697e93",
"HMAC-SHA1(dsa/fips_dsa_gen.c)= 78c879484fd849312ca4828b957df3842b70efc0",
"HMAC-SHA1(dsa/fips_dsa_selftest.c)= 7c2ba8d82feda2aadc8b769a3b6c4c25a6356e01",
"HMAC-SHA1(rand/fips_rand.c)= 29139e29f56f3ecd99f527af8742d5afb12f409a",
"HMAC-SHA1(rand/fips_rand.c)= 7e3964447a81cfe4e75df981827d14a5fe0c2923",
"HMAC-SHA1(rand/fips_rand.h)= bf009ea8963e79b1e414442ede9ae7010a03160b",
"HMAC-SHA1(rand/fips_rand_selftest.c)= d9c8985e08feecefafe667ad0119d444b42f807c",
"HMAC-SHA1(rsa/fips_rsa_eay.c)= 2596773a7af8f037427217b79f56858296961d66",
"HMAC-SHA1(rsa/fips_rsa_gen.c)= 713d2e0d7a1a682b1794f1224b7afe01272ba755",
"HMAC-SHA1(rsa/fips_rsa_selftest.c)= dcd0970a4de2d7f0d2333d6a3efb1ae350209b57",

View file

@ -22,8 +22,8 @@ TEST= fips_randtest.c
APPS=
LIB=$(TOP)/libcrypto.a
LIBSRC=fips_rand.c
LIBOBJ=fips_rand.o
LIBSRC=fips_rand.c fips_rand_selftest.c
LIBOBJ=fips_rand.o fips_rand_selftest.o
SRC= $(LIBSRC)
@ -62,6 +62,22 @@ tags:
tests:
top_fips_rngvs:
(cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) TARGET=fips_rngvs sub_target)
fips_rngvs: fips_rngvs.o $(TOP)/libcrypto.a
$(CC) $(CFLAGS) -o fips_rngvs fips_rngvs.o $(PEX_LIBS) $(TOP)/libcrypto.a $(EX_LIBS)
TOP=$(TOP) $(TOP)/fips/openssl_fips_fingerprint $(TOP)/libcrypto.a fips_rngvs
Q=../testvectors/rng/req
A=../testvectors/rng/rsp
fips_test: top_fips_rngvs
-rm -rf $A
mkdir $A
./fips_rngvs mct < $Q/MCT.req > $A/MCT.rsp
./fips_rngvs vst < $Q/VST.req > $A/VST.rsp
lint:
lint -DLINT $(INCLUDES) $(SRC)>fluff

View file

@ -90,6 +90,7 @@ static DES_cblock key1;
static DES_cblock key2;
static DES_key_schedule ks1,ks2;
static int key_set;
static int key_init;
static int test_mode;
static unsigned char test_faketime[8];
@ -153,7 +154,7 @@ static void fips_gettime(unsigned char buf[8])
if(test_mode)
{
fprintf(OPENSSL_stderr(),"WARNING!!! PRNG IN TEST MODE!!!\n");
/* fprintf(OPENSSL_stderr(),"WARNING!!! PRNG IN TEST MODE!!!\n"); */
memcpy(buf,test_faketime,sizeof test_faketime);
return;
}
@ -202,22 +203,23 @@ static void fips_rand_cleanup(void)
{
OPENSSL_cleanse(seed,sizeof seed);
n_seed=0;
o_seed=0;
key_init=0;
}
void FIPS_rand_seed(const void *buf_, FIPS_RAND_SIZE_T num)
{
const char *buf=buf_;
FIPS_RAND_SIZE_T n;
static int init;
/* If the key hasn't been set, we can't seed! */
if(!key_set)
return;
CRYPTO_w_lock(CRYPTO_LOCK_RAND);
if(!init)
if(!key_init)
{
init=1;
key_init=1;
DES_set_key(&key1,&ks1);
DES_set_key(&key2,&ks2);
}

View file

@ -0,0 +1,120 @@
/* ====================================================================
* Copyright (c) 2003 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <string.h>
#include <openssl/err.h>
#include <openssl/fips.h>
#include <openssl/rand.h>
#include <openssl/fips_rand.h>
#ifdef OPENSSL_FIPS
static struct
{
unsigned char key1[8];
unsigned char key2[8];
unsigned char seed[8];
unsigned char dt[8];
} init_iv[] =
{
{
{ 0x75, 0xc7, 0x1a, 0xe5, 0xa1, 0x1a, 0x23, 0x2c },
{ 0x40, 0x25, 0x6d, 0xcd, 0x94, 0xf7, 0x67, 0xb0 },
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xc8, 0x9a, 0x1d, 0x88, 0x8e, 0xd1, 0x2f, 0x3c },
},
{
{ 0x75, 0xc7, 0x1a, 0xe5, 0xa1, 0x1a, 0x23, 0x2c },
{ 0x40, 0x25, 0x6d, 0xcd, 0x94, 0xf7, 0x67, 0xb0 },
{ 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xc8, 0x9a, 0x1d, 0x88, 0x8e, 0xd1, 0x2f, 0x40 },
},
{
{ 0x75, 0xc7, 0x1a, 0xe5, 0xa1, 0x1a, 0x23, 0x2c },
{ 0x40, 0x25, 0x6d, 0xcd, 0x94, 0xf7, 0x67, 0xb0 },
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
{ 0xc8, 0x9a, 0x1d, 0x88, 0x8e, 0xd1, 0x2f, 0x7b },
},
};
static const unsigned char expected_ret[][8]=
{
{ 0x94, 0x4d, 0xc7, 0x21, 0x0d, 0x6d, 0x7f, 0xd7 },
{ 0x02, 0x43, 0x3c, 0x94, 0x17, 0xa3, 0x32, 0x6f },
{ 0xe7, 0xe2, 0xb2, 0x96, 0x4f, 0x36, 0xed, 0x41 },
};
void FIPS_corrupt_rng()
{
init_iv[0].dt[0]++;
}
int FIPS_selftest_rng()
{
int n;
for(n=0 ; n < 3 ; ++n)
{
unsigned char actual_ret[8];
FIPS_rand_method()->cleanup();
FIPS_set_prng_key(init_iv[n].key1,init_iv[n].key2);
FIPS_rand_seed(init_iv[n].seed,8);
FIPS_test_mode(1,init_iv[n].dt);
if ((FIPS_rand_method()->bytes(actual_ret, 8) <=0) || (memcmp(actual_ret,expected_ret[n],sizeof actual_ret)))
{
FIPS_test_mode(0,NULL);
FIPSerr(FIPS_F_FIPS_SELFTEST_RNG,FIPS_R_SELFTEST_FAILED);
return 0;
}
}
FIPS_test_mode(0,NULL);
return 1;
}
#endif

222
fips/rand/fips_rngvs.c Normal file
View file

@ -0,0 +1,222 @@
/*
* Crude test driver for processing the VST and MCT testvector files generated by the CMVP
* RNGVS product.
*
* Note the input files are assumed to have a _very_ specific format as described in the
* NIST document "The Random Number Generator Validation System (RNGVS)", May 25, 2004.
*
*/
#include <openssl/bn.h>
#include <openssl/dsa.h>
#include <openssl/fips.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/fips_rand.h>
#include <string.h>
int hex2bin(const char *in, unsigned char *out)
{
int n1, n2;
unsigned char ch;
for (n1=0,n2=0 ; in[n1] && in[n1] != '\n' ; )
{ /* first byte */
if ((in[n1] >= '0') && (in[n1] <= '9'))
ch = in[n1++] - '0';
else if ((in[n1] >= 'A') && (in[n1] <= 'F'))
ch = in[n1++] - 'A' + 10;
else if ((in[n1] >= 'a') && (in[n1] <= 'f'))
ch = in[n1++] - 'a' + 10;
else
return -1;
if(!in[n1])
{
out[n2++]=ch;
break;
}
out[n2] = ch << 4;
/* second byte */
if ((in[n1] >= '0') && (in[n1] <= '9'))
ch = in[n1++] - '0';
else if ((in[n1] >= 'A') && (in[n1] <= 'F'))
ch = in[n1++] - 'A' + 10;
else if ((in[n1] >= 'a') && (in[n1] <= 'f'))
ch = in[n1++] - 'a' + 10;
else
return -1;
out[n2++] |= ch;
}
return n2;
}
int bin2hex(const unsigned char *in,int len,char *out)
{
int n1, n2;
unsigned char ch;
for (n1=0,n2=0 ; n1 < len ; ++n1)
{
ch=in[n1] >> 4;
if (ch <= 0x09)
out[n2++]=ch+'0';
else
out[n2++]=ch-10+'a';
ch=in[n1] & 0x0f;
if(ch <= 0x09)
out[n2++]=ch+'0';
else
out[n2++]=ch-10+'a';
}
out[n2]='\0';
return n2;
}
void pv(const char *tag,const unsigned char *val,int len)
{
char obuf[2048];
bin2hex(val,len,obuf);
printf("%s = %s\n",tag,obuf);
}
void vst()
{
unsigned char key1[8];
unsigned char key2[8];
unsigned char v[8];
unsigned char dt[8];
unsigned char ret[8];
char buf[1024];
int n;
while(fgets(buf,sizeof buf,stdin) != NULL)
{
if(!strncmp(buf,"Key1 = ",7))
{
n=hex2bin(buf+7,key1);
pv("Key1",key1,n);
}
else if(!strncmp(buf,"Key2 = ",7))
{
n=hex2bin(buf+7,key2);
pv("Key1",key2,n);
}
else if(!strncmp(buf,"DT = ",5))
{
n=hex2bin(buf+5,dt);
pv("DT",dt,n);
}
else if(!strncmp(buf,"V = ",4))
{
n=hex2bin(buf+4,v);
pv("V",v,n);
FIPS_rand_method()->cleanup();
FIPS_set_prng_key(key1,key2);
FIPS_rand_seed(v,8);
FIPS_test_mode(1,dt);
if (FIPS_rand_method()->bytes(ret,8) <= 0)
{
FIPS_test_mode(0,NULL);
FIPSerr(FIPS_F_FIPS_SELFTEST_RNG,FIPS_R_SELFTEST_FAILED);
return;
}
pv("R",ret,8);
putc('\n',stdout);
}
else
fputs(buf,stdout);
}
}
void mct()
{
unsigned char key1[8];
unsigned char key2[8];
unsigned char v[8];
unsigned char dt[8];
unsigned char ret[8];
char buf[1024];
int n;
BIGNUM *bn;
BIGNUM *pbn;
bn = BN_new();
while(fgets(buf,sizeof buf,stdin) != NULL)
{
if(!strncmp(buf,"Key1 = ",7))
{
n=hex2bin(buf+7,key1);
pv("Key1",key1,n);
}
else if(!strncmp(buf,"Key2 = ",7))
{
n=hex2bin(buf+7,key2);
pv("Key1",key2,n);
}
else if(!strncmp(buf,"DT = ",5))
{
n=hex2bin(buf+5,dt);
pv("DT",dt,n);
}
else if(!strncmp(buf,"V = ",4))
{
int iter;
n=hex2bin(buf+4,v);
pv("V",v,n);
FIPS_rand_method()->cleanup();
FIPS_set_prng_key(key1,key2);
FIPS_rand_seed(v,8);
for (iter=0; iter < 10000; ++iter)
{
FIPS_test_mode(1,dt);
if (FIPS_rand_method()->bytes(ret,8) <= 0)
{
FIPS_test_mode(0,NULL);
FIPSerr(FIPS_F_FIPS_SELFTEST_RNG,FIPS_R_SELFTEST_FAILED);
return;
}
pbn = BN_bin2bn(dt,8,bn);
n = BN_add(bn,bn,BN_value_one());
n = BN_bn2bin(bn,dt);
}
pv("R",ret,8);
putc('\n',stdout);
}
else
fputs(buf,stdout);
}
BN_free(bn);
}
int main(int argc,char **argv)
{
if(argc != 2)
{
fprintf(stderr,"%s [mct|vst]\n",argv[0]);
exit(1);
}
if(!FIPS_mode_set(1,argv[0]))
{
ERR_load_crypto_strings();
ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE));
exit(1);
}
if(!strcmp(argv[1],"mct"))
mct();
else if(!strcmp(argv[1],"vst"))
vst();
else
{
fprintf(stderr,"Don't know how to %s.\n",argv[1]);
exit(1);
}
return 0;
}