mirror of
https://github.com/openssl/openssl.git
synced 2025-01-30 14:01:55 +08:00
Change RNG test to block oriented instead of request oriented, add option
to test a "stuck" DRBG.
This commit is contained in:
parent
a255e5bc98
commit
ded1999702
@ -71,6 +71,7 @@
|
|||||||
static ERR_STRING_DATA FIPS_str_functs[]=
|
static ERR_STRING_DATA FIPS_str_functs[]=
|
||||||
{
|
{
|
||||||
{ERR_FUNC(FIPS_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"},
|
{ERR_FUNC(FIPS_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"},
|
||||||
|
{ERR_FUNC(FIPS_F_DRBG_CPRNG_TEST), "DRBG_CPRNG_TEST"},
|
||||||
{ERR_FUNC(FIPS_F_DSA_BUILTIN_PARAMGEN), "DSA_BUILTIN_PARAMGEN"},
|
{ERR_FUNC(FIPS_F_DSA_BUILTIN_PARAMGEN), "DSA_BUILTIN_PARAMGEN"},
|
||||||
{ERR_FUNC(FIPS_F_DSA_BUILTIN_PARAMGEN2), "DSA_BUILTIN_PARAMGEN2"},
|
{ERR_FUNC(FIPS_F_DSA_BUILTIN_PARAMGEN2), "DSA_BUILTIN_PARAMGEN2"},
|
||||||
{ERR_FUNC(FIPS_F_DSA_DO_SIGN), "DSA_do_sign"},
|
{ERR_FUNC(FIPS_F_DSA_DO_SIGN), "DSA_do_sign"},
|
||||||
@ -139,6 +140,7 @@ static ERR_STRING_DATA FIPS_str_reasons[]=
|
|||||||
{ERR_REASON(FIPS_R_GENERATE_ERROR_UNDETECTED),"generate error undetected"},
|
{ERR_REASON(FIPS_R_GENERATE_ERROR_UNDETECTED),"generate error undetected"},
|
||||||
{ERR_REASON(FIPS_R_INSTANTIATE_ERROR) ,"instantiate error"},
|
{ERR_REASON(FIPS_R_INSTANTIATE_ERROR) ,"instantiate error"},
|
||||||
{ERR_REASON(FIPS_R_INSUFFICIENT_SECURITY_STRENGTH),"insufficient security strength"},
|
{ERR_REASON(FIPS_R_INSUFFICIENT_SECURITY_STRENGTH),"insufficient security strength"},
|
||||||
|
{ERR_REASON(FIPS_R_INTERNAL_ERROR) ,"internal error"},
|
||||||
{ERR_REASON(FIPS_R_INVALID_KEY_LENGTH) ,"invalid key length"},
|
{ERR_REASON(FIPS_R_INVALID_KEY_LENGTH) ,"invalid key length"},
|
||||||
{ERR_REASON(FIPS_R_IN_ERROR_STATE) ,"in error state"},
|
{ERR_REASON(FIPS_R_IN_ERROR_STATE) ,"in error state"},
|
||||||
{ERR_REASON(FIPS_R_KEY_TOO_SHORT) ,"key too short"},
|
{ERR_REASON(FIPS_R_KEY_TOO_SHORT) ,"key too short"},
|
||||||
|
@ -92,6 +92,7 @@ void FIPS_corrupt_ec_keygen(void);
|
|||||||
void FIPS_corrupt_rng(void);
|
void FIPS_corrupt_rng(void);
|
||||||
void FIPS_corrupt_drbg(void);
|
void FIPS_corrupt_drbg(void);
|
||||||
void FIPS_rng_stick(void);
|
void FIPS_rng_stick(void);
|
||||||
|
void FIPS_drbg_stick(void);
|
||||||
int FIPS_selftest_rng(void);
|
int FIPS_selftest_rng(void);
|
||||||
int FIPS_selftest_hmac(void);
|
int FIPS_selftest_hmac(void);
|
||||||
int FIPS_selftest_drbg(void);
|
int FIPS_selftest_drbg(void);
|
||||||
@ -188,6 +189,7 @@ void ERR_load_FIPS_strings(void);
|
|||||||
|
|
||||||
/* Function codes. */
|
/* Function codes. */
|
||||||
#define FIPS_F_DH_BUILTIN_GENPARAMS 100
|
#define FIPS_F_DH_BUILTIN_GENPARAMS 100
|
||||||
|
#define FIPS_F_DRBG_CPRNG_TEST 141
|
||||||
#define FIPS_F_DSA_BUILTIN_PARAMGEN 101
|
#define FIPS_F_DSA_BUILTIN_PARAMGEN 101
|
||||||
#define FIPS_F_DSA_BUILTIN_PARAMGEN2 126
|
#define FIPS_F_DSA_BUILTIN_PARAMGEN2 126
|
||||||
#define FIPS_F_DSA_DO_SIGN 102
|
#define FIPS_F_DSA_DO_SIGN 102
|
||||||
@ -253,6 +255,7 @@ void ERR_load_FIPS_strings(void);
|
|||||||
#define FIPS_R_GENERATE_ERROR_UNDETECTED 136
|
#define FIPS_R_GENERATE_ERROR_UNDETECTED 136
|
||||||
#define FIPS_R_INSTANTIATE_ERROR 125
|
#define FIPS_R_INSTANTIATE_ERROR 125
|
||||||
#define FIPS_R_INSUFFICIENT_SECURITY_STRENGTH 132
|
#define FIPS_R_INSUFFICIENT_SECURITY_STRENGTH 132
|
||||||
|
#define FIPS_R_INTERNAL_ERROR 143
|
||||||
#define FIPS_R_INVALID_KEY_LENGTH 109
|
#define FIPS_R_INVALID_KEY_LENGTH 109
|
||||||
#define FIPS_R_IN_ERROR_STATE 126
|
#define FIPS_R_IN_ERROR_STATE 126
|
||||||
#define FIPS_R_KEY_TOO_SHORT 108
|
#define FIPS_R_KEY_TOO_SHORT 108
|
||||||
|
@ -671,6 +671,7 @@ int main(int argc,char **argv)
|
|||||||
int do_corrupt_rsa_keygen = 0, do_corrupt_dsa_keygen = 0;
|
int do_corrupt_rsa_keygen = 0, do_corrupt_dsa_keygen = 0;
|
||||||
int bad_rsa = 0, bad_dsa = 0;
|
int bad_rsa = 0, bad_dsa = 0;
|
||||||
int do_rng_stick = 0;
|
int do_rng_stick = 0;
|
||||||
|
int do_drbg_stick = 0;
|
||||||
int no_exit = 0;
|
int no_exit = 0;
|
||||||
|
|
||||||
fips_algtest_init_nofips();
|
fips_algtest_init_nofips();
|
||||||
@ -727,6 +728,10 @@ int main(int argc,char **argv)
|
|||||||
do_rng_stick = 1;
|
do_rng_stick = 1;
|
||||||
no_exit = 1;
|
no_exit = 1;
|
||||||
printf("RNG test with stuck continuous test...\n");
|
printf("RNG test with stuck continuous test...\n");
|
||||||
|
} else if (!strcmp(argv[1], "drbgstick")) {
|
||||||
|
do_drbg_stick = 1;
|
||||||
|
no_exit = 1;
|
||||||
|
printf("DRBG test with stuck continuous test...\n");
|
||||||
} else {
|
} else {
|
||||||
printf("Bad argument \"%s\"\n", argv[1]);
|
printf("Bad argument \"%s\"\n", argv[1]);
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -756,6 +761,8 @@ int main(int argc,char **argv)
|
|||||||
FIPS_corrupt_dsa_keygen();
|
FIPS_corrupt_dsa_keygen();
|
||||||
if (do_corrupt_rsa_keygen)
|
if (do_corrupt_rsa_keygen)
|
||||||
FIPS_corrupt_rsa_keygen();
|
FIPS_corrupt_rsa_keygen();
|
||||||
|
if (do_drbg_stick)
|
||||||
|
FIPS_drbg_stick();
|
||||||
if (do_rng_stick)
|
if (do_rng_stick)
|
||||||
FIPS_rng_stick();
|
FIPS_rng_stick();
|
||||||
|
|
||||||
|
@ -330,14 +330,24 @@ static int drbg_ctr_generate(DRBG_CTX *dctx,
|
|||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
inc_128(cctx);
|
inc_128(cctx);
|
||||||
|
if (!(dctx->flags & DRBG_FLAG_TEST) && !dctx->lb_valid)
|
||||||
|
{
|
||||||
|
AES_encrypt(cctx->V, dctx->lb, &cctx->ks);
|
||||||
|
dctx->lb_valid = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (outlen < 16)
|
if (outlen < 16)
|
||||||
{
|
{
|
||||||
/* Use K as temp space as it will be updated */
|
/* Use K as temp space as it will be updated */
|
||||||
AES_encrypt(cctx->V, cctx->K, &cctx->ks);
|
AES_encrypt(cctx->V, cctx->K, &cctx->ks);
|
||||||
|
if (!drbg_cprng_test(dctx, cctx->K))
|
||||||
|
return 0;
|
||||||
memcpy(out, cctx->K, outlen);
|
memcpy(out, cctx->K, outlen);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
AES_encrypt(cctx->V, out, &cctx->ks);
|
AES_encrypt(cctx->V, out, &cctx->ks);
|
||||||
|
if (!drbg_cprng_test(dctx, out))
|
||||||
|
return 0;
|
||||||
out += 16;
|
out += 16;
|
||||||
outlen -= 16;
|
outlen -= 16;
|
||||||
if (outlen == 0)
|
if (outlen == 0)
|
||||||
|
@ -195,13 +195,23 @@ static int hash_gen(DRBG_CTX *dctx, unsigned char *out, size_t outlen)
|
|||||||
{
|
{
|
||||||
FIPS_digestinit(&hctx->mctx, hctx->md);
|
FIPS_digestinit(&hctx->mctx, hctx->md);
|
||||||
FIPS_digestupdate(&hctx->mctx, hctx->vtmp, dctx->seedlen);
|
FIPS_digestupdate(&hctx->mctx, hctx->vtmp, dctx->seedlen);
|
||||||
|
if (!(dctx->flags & DRBG_FLAG_TEST) && !dctx->lb_valid)
|
||||||
|
{
|
||||||
|
FIPS_digestfinal(&hctx->mctx, dctx->lb, NULL);
|
||||||
|
dctx->lb_valid = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (outlen < dctx->blocklength)
|
if (outlen < dctx->blocklength)
|
||||||
{
|
{
|
||||||
FIPS_digestfinal(&hctx->mctx, hctx->vtmp, NULL);
|
FIPS_digestfinal(&hctx->mctx, hctx->vtmp, NULL);
|
||||||
|
if (!drbg_cprng_test(dctx, hctx->vtmp))
|
||||||
|
return 0;
|
||||||
memcpy(out, hctx->vtmp, outlen);
|
memcpy(out, hctx->vtmp, outlen);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
FIPS_digestfinal(&hctx->mctx, out, NULL);
|
FIPS_digestfinal(&hctx->mctx, out, NULL);
|
||||||
|
if (!drbg_cprng_test(dctx, out))
|
||||||
|
return 0;
|
||||||
outlen -= dctx->blocklength;
|
outlen -= dctx->blocklength;
|
||||||
if (outlen == 0)
|
if (outlen == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -268,8 +268,7 @@ int FIPS_drbg_reseed(DRBG_CTX *dctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int fips_drbg_generate_internal(DRBG_CTX *dctx,
|
int FIPS_drbg_generate(DRBG_CTX *dctx, unsigned char *out, size_t outlen,
|
||||||
unsigned char *out, size_t outlen,
|
|
||||||
int strength, int prediction_resistance,
|
int strength, int prediction_resistance,
|
||||||
const unsigned char *adin, size_t adinlen)
|
const unsigned char *adin, size_t adinlen)
|
||||||
{
|
{
|
||||||
@ -323,76 +322,13 @@ static int fips_drbg_generate_internal(DRBG_CTX *dctx,
|
|||||||
if (r)
|
if (r)
|
||||||
{
|
{
|
||||||
if (!(dctx->flags & DRBG_FLAG_NOERR))
|
if (!(dctx->flags & DRBG_FLAG_NOERR))
|
||||||
FIPSerr(FIPS_F_FIPS_DRBG_GENERATE_INTERNAL, r);
|
FIPSerr(FIPS_F_FIPS_DRBG_GENERATE, r);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* external generate function: incorporates continuous RNG test if not
|
|
||||||
* in test mode.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int FIPS_drbg_generate(DRBG_CTX *dctx,
|
|
||||||
unsigned char *out, size_t outlen,
|
|
||||||
int strength, int prediction_resistance,
|
|
||||||
const unsigned char *adin, size_t adinlen)
|
|
||||||
{
|
|
||||||
unsigned char tmp[16], *pout;
|
|
||||||
size_t poutlen;
|
|
||||||
/* If test mode don't run continuous RNG test */
|
|
||||||
if (dctx->flags & DRBG_FLAG_TEST)
|
|
||||||
{
|
|
||||||
return fips_drbg_generate_internal(dctx, out, outlen,
|
|
||||||
strength,
|
|
||||||
prediction_resistance,
|
|
||||||
adin, adinlen);
|
|
||||||
}
|
|
||||||
/* If this is the first call generate block and save buffer */
|
|
||||||
if (!dctx->lb_valid)
|
|
||||||
{
|
|
||||||
if (!fips_drbg_generate_internal(dctx, dctx->lb, 16,
|
|
||||||
strength, prediction_resistance,
|
|
||||||
adin, adinlen))
|
|
||||||
return 0;
|
|
||||||
dctx->lb_valid = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If request less that 16 bytes request 16 in temp buffer */
|
|
||||||
|
|
||||||
if (outlen < 16)
|
|
||||||
{
|
|
||||||
pout = tmp;
|
|
||||||
poutlen = 16;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pout = out;
|
|
||||||
poutlen = outlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Generate data */
|
|
||||||
if (!fips_drbg_generate_internal(dctx, pout, poutlen,
|
|
||||||
strength, prediction_resistance,
|
|
||||||
adin, adinlen))
|
|
||||||
return 0;
|
|
||||||
/* Compare to last block for continuous PRNG test */
|
|
||||||
if (!memcmp(pout, dctx->lb, 16))
|
|
||||||
{
|
|
||||||
FIPSerr(FIPS_F_FIPS_DRBG_GENERATE, FIPS_R_DRBG_STUCK);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* Update last block */
|
|
||||||
memcpy(dctx->lb, pout, 16);
|
|
||||||
/* Copy to output buffer if needed */
|
|
||||||
if (outlen < 16)
|
|
||||||
memcpy(out, pout, outlen);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int FIPS_drbg_uninstantiate(DRBG_CTX *dctx)
|
int FIPS_drbg_uninstantiate(DRBG_CTX *dctx)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
@ -461,3 +397,37 @@ int FIPS_drbg_get_strength(DRBG_CTX *dctx)
|
|||||||
{
|
{
|
||||||
return dctx->strength;
|
return dctx->strength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int drbg_stick = 0;
|
||||||
|
|
||||||
|
void FIPS_drbg_stick(void)
|
||||||
|
{
|
||||||
|
drbg_stick = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Continuous DRBG utility function */
|
||||||
|
int drbg_cprng_test(DRBG_CTX *dctx, const unsigned char *out)
|
||||||
|
{
|
||||||
|
/* No CPRNG in test mode */
|
||||||
|
if (dctx->flags & DRBG_FLAG_TEST)
|
||||||
|
return 1;
|
||||||
|
/* Check block is valid: should never happen */
|
||||||
|
if (dctx->lb_valid == 0)
|
||||||
|
{
|
||||||
|
FIPSerr(FIPS_F_DRBG_CPRNG_TEST, FIPS_R_INTERNAL_ERROR);
|
||||||
|
fips_set_selftest_fail();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (drbg_stick)
|
||||||
|
memcpy(dctx->lb, out, dctx->blocklength);
|
||||||
|
/* Check against last block: fail if match */
|
||||||
|
if (!memcmp(dctx->lb, out, dctx->blocklength))
|
||||||
|
{
|
||||||
|
FIPSerr(FIPS_F_DRBG_CPRNG_TEST, FIPS_R_DRBG_STUCK);
|
||||||
|
fips_set_selftest_fail();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* Save last block for next comparison */
|
||||||
|
memcpy(dctx->lb, out, dctx->blocklength);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@ -117,6 +117,13 @@ static int fips_drbg_bytes(unsigned char *out, int count)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fips_drbg_pseudo(unsigned char *out, int count)
|
||||||
|
{
|
||||||
|
if (fips_drbg_bytes(out, count) <= 0)
|
||||||
|
return -1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int fips_drbg_status(void)
|
static int fips_drbg_status(void)
|
||||||
{
|
{
|
||||||
DRBG_CTX *dctx = &ossl_dctx;
|
DRBG_CTX *dctx = &ossl_dctx;
|
||||||
@ -168,7 +175,7 @@ static const RAND_METHOD rand_drbg_meth =
|
|||||||
fips_drbg_bytes,
|
fips_drbg_bytes,
|
||||||
fips_drbg_cleanup,
|
fips_drbg_cleanup,
|
||||||
fips_drbg_add,
|
fips_drbg_add,
|
||||||
fips_drbg_bytes,
|
fips_drbg_pseudo,
|
||||||
fips_drbg_status
|
fips_drbg_status
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -100,6 +100,10 @@ struct drbg_ctr_ctx_st
|
|||||||
/* A default maximum length: larger than any reasonable value used in pratice */
|
/* A default maximum length: larger than any reasonable value used in pratice */
|
||||||
|
|
||||||
#define DRBG_MAX_LENGTH 0x7ffffff0
|
#define DRBG_MAX_LENGTH 0x7ffffff0
|
||||||
|
/* Maximum DRBG block length: all md sizes are bigger than cipher blocks sizes
|
||||||
|
* so use max digest length.
|
||||||
|
*/
|
||||||
|
#define DRBG_MAX_BLOCK EVP_MAX_MD_SIZE
|
||||||
|
|
||||||
/* DRBG context structure */
|
/* DRBG context structure */
|
||||||
|
|
||||||
@ -163,7 +167,7 @@ struct drbg_ctx_st
|
|||||||
|
|
||||||
/* Continuous random number test temporary area */
|
/* Continuous random number test temporary area */
|
||||||
/* Last block */
|
/* Last block */
|
||||||
unsigned char lb[16];
|
unsigned char lb[EVP_MAX_MD_SIZE];
|
||||||
/* set if lb is valid */
|
/* set if lb is valid */
|
||||||
int lb_valid;
|
int lb_valid;
|
||||||
|
|
||||||
@ -181,3 +185,4 @@ struct drbg_ctx_st
|
|||||||
int fips_drbg_ctr_init(DRBG_CTX *dctx);
|
int fips_drbg_ctr_init(DRBG_CTX *dctx);
|
||||||
int fips_drbg_hash_init(DRBG_CTX *dctx);
|
int fips_drbg_hash_init(DRBG_CTX *dctx);
|
||||||
int fips_drbg_kat(DRBG_CTX *dctx, int nid, unsigned int flags);
|
int fips_drbg_kat(DRBG_CTX *dctx, int nid, unsigned int flags);
|
||||||
|
int drbg_cprng_test(DRBG_CTX *dctx, const unsigned char *out);
|
||||||
|
Loading…
Reference in New Issue
Block a user