Improve selftests, check for stuck PRNG(!).
This commit is contained in:
parent
0ae3ca9ec4
commit
a5ad942b70
@ -128,6 +128,7 @@ void ERR_load_RAND_strings(void);
|
|||||||
/* Reason codes. */
|
/* Reason codes. */
|
||||||
#define RAND_R_NON_FIPS_METHOD 101
|
#define RAND_R_NON_FIPS_METHOD 101
|
||||||
#define RAND_R_PRNG_NOT_SEEDED 100
|
#define RAND_R_PRNG_NOT_SEEDED 100
|
||||||
|
#define RAND_R_PRNG_STUCK 102
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* crypto/rand/rand_err.c */
|
/* crypto/rand/rand_err.c */
|
||||||
/* ====================================================================
|
/* ====================================================================
|
||||||
* Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved.
|
* Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@ -76,6 +76,7 @@ static ERR_STRING_DATA RAND_str_reasons[]=
|
|||||||
{
|
{
|
||||||
{RAND_R_NON_FIPS_METHOD ,"non fips method"},
|
{RAND_R_NON_FIPS_METHOD ,"non fips method"},
|
||||||
{RAND_R_PRNG_NOT_SEEDED ,"PRNG not seeded"},
|
{RAND_R_PRNG_NOT_SEEDED ,"PRNG not seeded"},
|
||||||
|
{RAND_R_PRNG_STUCK ,"prng stuck"},
|
||||||
{0,NULL}
|
{0,NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
SHA1(fips_aes_core.c)= 4cad001926dce3593181541ea19207256593171a
|
SHA1(fips_aes_core.c)= 4cad001926dce3593181541ea19207256593171a
|
||||||
SHA1(fips_aes_selftest.c)= b41f520aa90f813de815ee77ade4e7c73ef147b0
|
SHA1(fips_aes_selftest.c)= 8f270e559d34a18b3771d7f0098b77dd7bf168c5
|
||||||
SHA1(fips_aes_locl.h)= a3c01d9a4f9d5211e9e785852f6f1a2febfd73b6
|
SHA1(fips_aes_locl.h)= a3c01d9a4f9d5211e9e785852f6f1a2febfd73b6
|
||||||
|
@ -74,6 +74,7 @@ int FIPS_selftest_aes()
|
|||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
/* Encrypt and check against known ciphertext */
|
||||||
for(n=0 ; n < 1 ; ++n)
|
for(n=0 ; n < 1 ; ++n)
|
||||||
{
|
{
|
||||||
AES_KEY key;
|
AES_KEY key;
|
||||||
@ -87,6 +88,20 @@ int FIPS_selftest_aes()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Decrypt and check against known plaintext */
|
||||||
|
for(n=0 ; n < 1 ; ++n)
|
||||||
|
{
|
||||||
|
AES_KEY key;
|
||||||
|
unsigned char buf[16];
|
||||||
|
|
||||||
|
AES_set_decrypt_key(tests[n].key,128,&key);
|
||||||
|
AES_decrypt(tests[n].ciphertext,buf,&key);
|
||||||
|
if(memcmp(buf,tests[n].plaintext,sizeof buf))
|
||||||
|
{
|
||||||
|
FIPSerr(FIPS_F_FIPS_SELFTEST_AES,FIPS_R_SELFTEST_FAILED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
SHA1(fips_des_enc.c)= 41388beadcafe125a8025968ff91b7dc60b96c49
|
SHA1(fips_des_enc.c)= 41388beadcafe125a8025968ff91b7dc60b96c49
|
||||||
SHA1(fips_des_selftest.c)= d81ee4db762d89cca749138a99100d342f195665
|
SHA1(fips_des_selftest.c)= 1236ecc25bcbd5ad6af8c396426d6c7783cfe941
|
||||||
SHA1(fips_set_key.c)= 1e3dc1e0d02f0ab4d8fdd5e1f4db284cad1510f4
|
SHA1(fips_set_key.c)= 1e3dc1e0d02f0ab4d8fdd5e1f4db284cad1510f4
|
||||||
SHA1(fips_des_locl.h)= a4cf60ca32476a2483b3e4460ec9a19c0444fd20
|
SHA1(fips_des_locl.h)= a4cf60ca32476a2483b3e4460ec9a19c0444fd20
|
||||||
|
@ -73,10 +73,36 @@ static struct
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct
|
||||||
|
{
|
||||||
|
DES_cblock key1;
|
||||||
|
DES_cblock key2;
|
||||||
|
DES_cblock key3;
|
||||||
|
unsigned char plaintext[8];
|
||||||
|
unsigned char ciphertext[8];
|
||||||
|
} tests3[]=
|
||||||
|
{
|
||||||
|
{
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
||||||
|
{ 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10 },
|
||||||
|
{ 0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0 },
|
||||||
|
{ 0x8f,0x8f,0xbf,0x9b,0x5d,0x48,0xb4,0x1c},
|
||||||
|
{ 0x59,0x8c,0xe5,0xd3,0x6c,0xa2,0xea,0x1b},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ 0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,0xFE },
|
||||||
|
{ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF },
|
||||||
|
{ 0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4 },
|
||||||
|
{ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF },
|
||||||
|
{ 0x11,0x25,0xb0,0x35,0xbe,0xa0,0x82,0x86 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
int FIPS_selftest_des()
|
int FIPS_selftest_des()
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
/* Encrypt/decrypt with DES and compare to known answers */
|
||||||
for(n=0 ; n < 2 ; ++n)
|
for(n=0 ; n < 2 ; ++n)
|
||||||
{
|
{
|
||||||
DES_key_schedule key;
|
DES_key_schedule key;
|
||||||
@ -89,7 +115,37 @@ int FIPS_selftest_des()
|
|||||||
FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
|
FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
DES_ecb_encrypt(&tests[n].ciphertext,&buf,&key,0);
|
||||||
|
if(memcmp(buf,tests[n].plaintext,sizeof buf))
|
||||||
|
{
|
||||||
|
FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Encrypt/decrypt with 3DES and compare to known answers */
|
||||||
|
for(n=0 ; n < 2 ; ++n)
|
||||||
|
{
|
||||||
|
DES_key_schedule key1, key2, key3;
|
||||||
|
unsigned char buf[8];
|
||||||
|
|
||||||
|
DES_set_key(&tests3[n].key1,&key1);
|
||||||
|
DES_set_key(&tests3[n].key2,&key2);
|
||||||
|
DES_set_key(&tests3[n].key3,&key3);
|
||||||
|
DES_ecb3_encrypt(tests3[n].plaintext,buf,&key1,&key2,&key3,1);
|
||||||
|
if(memcmp(buf,tests3[n].ciphertext,sizeof buf))
|
||||||
|
{
|
||||||
|
FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DES_ecb3_encrypt(tests3[n].ciphertext,buf,&key1,&key2,&key3,0);
|
||||||
|
if(memcmp(buf,tests3[n].plaintext,sizeof buf))
|
||||||
|
{
|
||||||
|
FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
SHA1(fips_rand.c)= 2c86af552515bd1f58b3011d1958ea975afaa816
|
SHA1(fips_rand.c)= af88aebd4897e9d2ef593969b50f80c2cdf120d9
|
||||||
SHA1(fips_rand.h)= da5ee76588070c97d47c939d069d250a1476a080
|
SHA1(fips_rand.h)= da5ee76588070c97d47c939d069d250a1476a080
|
||||||
|
@ -93,11 +93,14 @@ RAND_METHOD rand_fips_meth=
|
|||||||
fips_rand_status
|
fips_rand_status
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int second;
|
||||||
|
|
||||||
void FIPS_set_prng_key(const unsigned char k1[8],const unsigned char k2[8])
|
void FIPS_set_prng_key(const unsigned char k1[8],const unsigned char k2[8])
|
||||||
{
|
{
|
||||||
memcpy(&key1,k1,sizeof key1);
|
memcpy(&key1,k1,sizeof key1);
|
||||||
memcpy(&key2,k2,sizeof key2);
|
memcpy(&key2,k2,sizeof key2);
|
||||||
key_set=1;
|
key_set=1;
|
||||||
|
second=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FIPS_test_mode(int test,const unsigned char faketime[8])
|
void FIPS_test_mode(int test,const unsigned char faketime[8])
|
||||||
@ -115,9 +118,6 @@ int FIPS_rand_seeded()
|
|||||||
static void fips_gettime(unsigned char buf[8])
|
static void fips_gettime(unsigned char buf[8])
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
#ifndef GETPID_IS_MEANINGLESS
|
|
||||||
long pid;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(test_mode)
|
if(test_mode)
|
||||||
{
|
{
|
||||||
@ -130,6 +130,7 @@ static void fips_gettime(unsigned char buf[8])
|
|||||||
memcpy (&buf[0],&tv.tv_sec,4);
|
memcpy (&buf[0],&tv.tv_sec,4);
|
||||||
memcpy (&buf[4],&tv.tv_usec,4);
|
memcpy (&buf[4],&tv.tv_usec,4);
|
||||||
|
|
||||||
|
#if 0 /* This eminently sensible strategy is not acceptable to NIST. Sigh. */
|
||||||
#ifndef GETPID_IS_MEANINGLESS
|
#ifndef GETPID_IS_MEANINGLESS
|
||||||
/* we mix in the PID to ensure that after a fork the children don't give
|
/* we mix in the PID to ensure that after a fork the children don't give
|
||||||
* the same results as each other
|
* the same results as each other
|
||||||
@ -139,6 +140,7 @@ static void fips_gettime(unsigned char buf[8])
|
|||||||
if((pid&0xffff0000) == 0)
|
if((pid&0xffff0000) == 0)
|
||||||
pid<<=16;
|
pid<<=16;
|
||||||
*(long *)&buf[0]^=pid;
|
*(long *)&buf[0]^=pid;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,6 +206,7 @@ static int fips_rand_bytes(unsigned char *buf,int num)
|
|||||||
unsigned char timeseed[8];
|
unsigned char timeseed[8];
|
||||||
unsigned char intermediate[SEED_SIZE];
|
unsigned char intermediate[SEED_SIZE];
|
||||||
unsigned char output[SEED_SIZE];
|
unsigned char output[SEED_SIZE];
|
||||||
|
static unsigned char previous[SEED_SIZE];
|
||||||
|
|
||||||
if(n_seed < sizeof seed)
|
if(n_seed < sizeof seed)
|
||||||
{
|
{
|
||||||
@ -229,6 +232,14 @@ static int fips_rand_bytes(unsigned char *buf,int num)
|
|||||||
t[l]=output[l]^seed[l];
|
t[l]=output[l]^seed[l];
|
||||||
fips_rand_encrypt(seed,t);
|
fips_rand_encrypt(seed,t);
|
||||||
|
|
||||||
|
if(second && !memcmp(output,previous,sizeof previous))
|
||||||
|
{
|
||||||
|
RANDerr(RAND_F_FIPS_RAND_BYTES,RAND_R_PRNG_STUCK);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memcpy(previous,output,sizeof previous);
|
||||||
|
second=1;
|
||||||
|
|
||||||
l=SEED_SIZE < num-n ? SEED_SIZE : num-n;
|
l=SEED_SIZE < num-n ? SEED_SIZE : num-n;
|
||||||
memcpy(buf+n,output,l);
|
memcpy(buf+n,output,l);
|
||||||
n+=l;
|
n+=l;
|
||||||
|
@ -107,6 +107,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
#include <openssl/fips_rand.h>
|
#include <openssl/fips_rand.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
|
||||||
#include "e_os.h"
|
#include "e_os.h"
|
||||||
|
|
||||||
@ -138,13 +139,13 @@ typedef struct
|
|||||||
/* FIXME: these test vectors are made up! */
|
/* FIXME: these test vectors are made up! */
|
||||||
static PRNGtest t1=
|
static PRNGtest t1=
|
||||||
{
|
{
|
||||||
{ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
{ { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 },
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
{ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f },
|
||||||
},
|
},
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
||||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
|
{ 0x33,0xc3,0xdf,0xfe,0x60,0x60,0x49,0x9e },
|
||||||
{ 0x8c,0xa6,0x4d,0xe9,0xc1,0xb1,0x23,0xa7 }
|
{ 0x40,0x08,0x95,0x4d,0xb1,0x82,0x98,0x86 }
|
||||||
};
|
};
|
||||||
static PRNGtest t2=
|
static PRNGtest t2=
|
||||||
{
|
{
|
||||||
@ -152,8 +153,8 @@ static PRNGtest t2=
|
|||||||
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff } },
|
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff } },
|
||||||
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },
|
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },
|
||||||
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },
|
{ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },
|
||||||
{ 0xcd,0x57,0xcb,0xfa,0x08,0xd8,0xdb,0x3a },
|
{ 0x65,0xf1,0xa4,0x07,0x42,0x38,0xd5,0x25 },
|
||||||
{ 0x05,0xad,0x17,0xbd,0xd8,0x32,0x96,0x79 }
|
{ 0x99,0xba,0x8f,0xd2,0x88,0xad,0xf8,0x34 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static void dump(const unsigned char *b,int n)
|
static void dump(const unsigned char *b,int n)
|
||||||
@ -190,10 +191,18 @@ static void run_test(const PRNGtest *t)
|
|||||||
FIPS_test_mode(1,t->time);
|
FIPS_test_mode(1,t->time);
|
||||||
RAND_seed(t->seed,sizeof t->seed);
|
RAND_seed(t->seed,sizeof t->seed);
|
||||||
|
|
||||||
RAND_bytes(buf,8);
|
if(RAND_bytes(buf,8) != 8)
|
||||||
|
{
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
compare(buf,t->block1,8);
|
compare(buf,t->block1,8);
|
||||||
for(n=0 ; n < 99 ; ++n)
|
for(n=0 ; n < 99 ; ++n)
|
||||||
RAND_bytes(buf,8);
|
if(RAND_bytes(buf,8) != 8)
|
||||||
|
{
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
compare(buf,t->block100,8);
|
compare(buf,t->block100,8);
|
||||||
FIPS_test_mode(0,NULL);
|
FIPS_test_mode(0,NULL);
|
||||||
}
|
}
|
||||||
@ -208,6 +217,7 @@ int main()
|
|||||||
/*double d; */
|
/*double d; */
|
||||||
long d;
|
long d;
|
||||||
|
|
||||||
|
ERR_load_crypto_strings();
|
||||||
RAND_set_rand_method(&rand_fips_meth);
|
RAND_set_rand_method(&rand_fips_meth);
|
||||||
|
|
||||||
run_test(&t1);
|
run_test(&t1);
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
SHA1(fips_rsa_eay.c)= eacbcc656f1f046509abb9cc0207880b58ae8b90
|
SHA1(fips_rsa_eay.c)= eacbcc656f1f046509abb9cc0207880b58ae8b90
|
||||||
SHA1(fips_rsa_gen.c)= bfc4d7204f714a354a2e652318c5e82518441427
|
SHA1(fips_rsa_gen.c)= bfc4d7204f714a354a2e652318c5e82518441427
|
||||||
SHA1(fips_rsa_selftest.c)= f0a9683b29b3e231067f840424727413e811cbfc
|
SHA1(fips_rsa_selftest.c)= 0106c4c565833ad2c8975b7d38765038a58f037c
|
||||||
|
@ -156,8 +156,13 @@ int FIPS_selftest_rsa()
|
|||||||
"\xef\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34\x56\x78\x9a\xbc\xde";
|
"\xef\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34\x56\x78\x9a\xbc\xde";
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
/* Perform pairwise consistency test by: ... */
|
||||||
|
|
||||||
key=RSA_new();
|
key=RSA_new();
|
||||||
clen=setrsakey(key,expected_ctext);
|
clen=setrsakey(key,expected_ctext);
|
||||||
|
/* ...1) apply public key to plaintext, resulting ciphertext must be
|
||||||
|
* different
|
||||||
|
*/
|
||||||
n=RSA_public_encrypt(sizeof(original_ptext)-1,original_ptext,ctext,key,
|
n=RSA_public_encrypt(sizeof(original_ptext)-1,original_ptext,ctext,key,
|
||||||
RSA_NO_PADDING);
|
RSA_NO_PADDING);
|
||||||
if(n < 0)
|
if(n < 0)
|
||||||
@ -170,6 +175,14 @@ int FIPS_selftest_rsa()
|
|||||||
FIPSerr(FIPS_F_FIPS_SELFTEST_RSA,FIPS_R_SELFTEST_FAILED);
|
FIPSerr(FIPS_F_FIPS_SELFTEST_RSA,FIPS_R_SELFTEST_FAILED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if(!memcmp(ctext,original_ptext,n))
|
||||||
|
{
|
||||||
|
FIPSerr(FIPS_F_FIPS_SELFTEST_RSA,FIPS_R_SELFTEST_FAILED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* ...2) apply private key to ciphertext and compare result to
|
||||||
|
* original plaintext; results must be equal
|
||||||
|
*/
|
||||||
n=RSA_private_decrypt(n,ctext,ptext,key,RSA_NO_PADDING);
|
n=RSA_private_decrypt(n,ctext,ptext,key,RSA_NO_PADDING);
|
||||||
if(n < 0)
|
if(n < 0)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user