mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-30 05:35:31 +00:00
Bugzilla Bug 318966: implemented the tests for the NIST RNG Validation
System. r=glen.beasley. Modified file: fipstest.c Added file: rng.sh
This commit is contained in:
parent
c20388e588
commit
db3d31ac92
@ -2556,17 +2556,253 @@ loser:
|
||||
}
|
||||
#endif /* NSS_ENABLE_ECC */
|
||||
|
||||
void do_random()
|
||||
/*
|
||||
* Perform the RNG Variable Seed Test (VST) for the RNG algorithm
|
||||
* "DSA - Generation of X", used both as specified and as a generic
|
||||
* purpose RNG. The presence of "Q = ..." in the REQUEST file
|
||||
* indicates we are using the algorithm as specified.
|
||||
*
|
||||
* reqfn is the pathname of the REQUEST file.
|
||||
*
|
||||
* The output RESPONSE file is written to stdout.
|
||||
*/
|
||||
void
|
||||
rng_vst(char *reqfn)
|
||||
{
|
||||
int i, j, k = 0;
|
||||
unsigned char buf[500];
|
||||
for (i=0; i<5; i++) {
|
||||
RNG_GenerateGlobalRandomBytes(buf, sizeof buf);
|
||||
for (j=0; j<sizeof buf / 2; j++) {
|
||||
printf("0x%02x%02x", buf[2*j], buf[2*j+1]);
|
||||
if (++k % 8 == 0) printf("\n"); else printf(" ");
|
||||
char buf[256]; /* holds one line from the input REQUEST file.
|
||||
* needs to be large enough to hold the longest
|
||||
* line "XSeed = <128 hex digits>\n".
|
||||
*/
|
||||
FILE *rngreq; /* input stream from the REQUEST file */
|
||||
FILE *rngresp; /* output stream to the RESPONSE file */
|
||||
unsigned int i, j;
|
||||
unsigned char Q[DSA_SUBPRIME_LEN];
|
||||
PRBool hasQ = PR_FALSE;
|
||||
unsigned int b; /* 160 <= b <= 512, b is a multiple of 8 */
|
||||
unsigned char XKey[512/8];
|
||||
unsigned char XSeed[512/8];
|
||||
unsigned char GENX[2*SHA1_LENGTH];
|
||||
unsigned char DSAX[DSA_SUBPRIME_LEN];
|
||||
SECStatus rv;
|
||||
|
||||
rngreq = fopen(reqfn, "r");
|
||||
rngresp = stdout;
|
||||
while (fgets(buf, sizeof buf, rngreq) != NULL) {
|
||||
/* a comment or blank line */
|
||||
if (buf[0] == '#' || buf[0] == '\n') {
|
||||
fputs(buf, rngresp);
|
||||
continue;
|
||||
}
|
||||
/* [Xchange - SHA1] */
|
||||
if (buf[0] == '[') {
|
||||
fputs(buf, rngresp);
|
||||
continue;
|
||||
}
|
||||
/* Q = ... */
|
||||
if (buf[0] == 'Q') {
|
||||
i = 1;
|
||||
while (isspace(buf[i]) || buf[i] == '=') {
|
||||
i++;
|
||||
}
|
||||
for (j=0; j<sizeof Q; i+=2,j++) {
|
||||
hex_from_2char(&buf[i], &Q[j]);
|
||||
}
|
||||
fputs(buf, rngresp);
|
||||
hasQ = PR_TRUE;
|
||||
continue;
|
||||
}
|
||||
/* "COUNT = x" begins a new data set */
|
||||
if (strncmp(buf, "COUNT", 5) == 0) {
|
||||
/* zeroize the variables for the test with this data set */
|
||||
b = 0;
|
||||
memset(XKey, 0, sizeof XKey);
|
||||
memset(XSeed, 0, sizeof XSeed);
|
||||
fputs(buf, rngresp);
|
||||
continue;
|
||||
}
|
||||
/* b = ... */
|
||||
if (buf[0] == 'b') {
|
||||
i = 1;
|
||||
while (isspace(buf[i]) || buf[i] == '=') {
|
||||
i++;
|
||||
}
|
||||
b = atoi(&buf[i]);
|
||||
if (b < 160 || b > 512 || b%8 != 0) {
|
||||
goto loser;
|
||||
}
|
||||
fputs(buf, rngresp);
|
||||
continue;
|
||||
}
|
||||
/* XKey = ... */
|
||||
if (strncmp(buf, "XKey", 4) == 0) {
|
||||
i = 4;
|
||||
while (isspace(buf[i]) || buf[i] == '=') {
|
||||
i++;
|
||||
}
|
||||
for (j=0; j<b/8; i+=2,j++) {
|
||||
hex_from_2char(&buf[i], &XKey[j]);
|
||||
}
|
||||
fputs(buf, rngresp);
|
||||
continue;
|
||||
}
|
||||
/* XSeed = ... */
|
||||
if (strncmp(buf, "XSeed", 5) == 0) {
|
||||
i = 5;
|
||||
while (isspace(buf[i]) || buf[i] == '=') {
|
||||
i++;
|
||||
}
|
||||
for (j=0; j<b/8; i+=2,j++) {
|
||||
hex_from_2char(&buf[i], &XSeed[j]);
|
||||
}
|
||||
fputs(buf, rngresp);
|
||||
|
||||
rv = FIPS186Change_GenerateX(XKey, XSeed, GENX);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
fputs("X = ", rngresp);
|
||||
if (hasQ) {
|
||||
rv = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
to_hex_str(buf, DSAX, sizeof DSAX);
|
||||
} else {
|
||||
to_hex_str(buf, GENX, sizeof GENX);
|
||||
}
|
||||
fputs(buf, rngresp);
|
||||
fputc('\n', rngresp);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
loser:
|
||||
fclose(rngreq);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the RNG Monte Carlo Test (MCT) for the RNG algorithm
|
||||
* "DSA - Generation of X", used both as specified and as a generic
|
||||
* purpose RNG. The presence of "Q = ..." in the REQUEST file
|
||||
* indicates we are using the algorithm as specified.
|
||||
*
|
||||
* reqfn is the pathname of the REQUEST file.
|
||||
*
|
||||
* The output RESPONSE file is written to stdout.
|
||||
*/
|
||||
void
|
||||
rng_mct(char *reqfn)
|
||||
{
|
||||
char buf[256]; /* holds one line from the input REQUEST file.
|
||||
* needs to be large enough to hold the longest
|
||||
* line "XSeed = <128 hex digits>\n".
|
||||
*/
|
||||
FILE *rngreq; /* input stream from the REQUEST file */
|
||||
FILE *rngresp; /* output stream to the RESPONSE file */
|
||||
unsigned int i, j;
|
||||
unsigned char Q[DSA_SUBPRIME_LEN];
|
||||
PRBool hasQ = PR_FALSE;
|
||||
unsigned int b; /* 160 <= b <= 512, b is a multiple of 8 */
|
||||
unsigned char XKey[512/8];
|
||||
unsigned char XSeed[512/8];
|
||||
unsigned char GENX[2*SHA1_LENGTH];
|
||||
unsigned char DSAX[DSA_SUBPRIME_LEN];
|
||||
SECStatus rv;
|
||||
|
||||
rngreq = fopen(reqfn, "r");
|
||||
rngresp = stdout;
|
||||
while (fgets(buf, sizeof buf, rngreq) != NULL) {
|
||||
/* a comment or blank line */
|
||||
if (buf[0] == '#' || buf[0] == '\n') {
|
||||
fputs(buf, rngresp);
|
||||
continue;
|
||||
}
|
||||
/* [Xchange - SHA1] */
|
||||
if (buf[0] == '[') {
|
||||
fputs(buf, rngresp);
|
||||
continue;
|
||||
}
|
||||
/* Q = ... */
|
||||
if (buf[0] == 'Q') {
|
||||
i = 1;
|
||||
while (isspace(buf[i]) || buf[i] == '=') {
|
||||
i++;
|
||||
}
|
||||
for (j=0; j<sizeof Q; i+=2,j++) {
|
||||
hex_from_2char(&buf[i], &Q[j]);
|
||||
}
|
||||
fputs(buf, rngresp);
|
||||
hasQ = PR_TRUE;
|
||||
continue;
|
||||
}
|
||||
/* "COUNT = x" begins a new data set */
|
||||
if (strncmp(buf, "COUNT", 5) == 0) {
|
||||
/* zeroize the variables for the test with this data set */
|
||||
b = 0;
|
||||
memset(XKey, 0, sizeof XKey);
|
||||
memset(XSeed, 0, sizeof XSeed);
|
||||
fputs(buf, rngresp);
|
||||
continue;
|
||||
}
|
||||
/* b = ... */
|
||||
if (buf[0] == 'b') {
|
||||
i = 1;
|
||||
while (isspace(buf[i]) || buf[i] == '=') {
|
||||
i++;
|
||||
}
|
||||
b = atoi(&buf[i]);
|
||||
if (b < 160 || b > 512 || b%8 != 0) {
|
||||
goto loser;
|
||||
}
|
||||
fputs(buf, rngresp);
|
||||
continue;
|
||||
}
|
||||
/* XKey = ... */
|
||||
if (strncmp(buf, "XKey", 4) == 0) {
|
||||
i = 4;
|
||||
while (isspace(buf[i]) || buf[i] == '=') {
|
||||
i++;
|
||||
}
|
||||
for (j=0; j<b/8; i+=2,j++) {
|
||||
hex_from_2char(&buf[i], &XKey[j]);
|
||||
}
|
||||
fputs(buf, rngresp);
|
||||
continue;
|
||||
}
|
||||
/* XSeed = ... */
|
||||
if (strncmp(buf, "XSeed", 5) == 0) {
|
||||
unsigned int k;
|
||||
i = 5;
|
||||
while (isspace(buf[i]) || buf[i] == '=') {
|
||||
i++;
|
||||
}
|
||||
for (j=0; j<b/8; i+=2,j++) {
|
||||
hex_from_2char(&buf[i], &XSeed[j]);
|
||||
}
|
||||
fputs(buf, rngresp);
|
||||
|
||||
for (k = 0; k < 10000; k++) {
|
||||
rv = FIPS186Change_GenerateX(XKey, XSeed, GENX);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
}
|
||||
fputs("X = ", rngresp);
|
||||
if (hasQ) {
|
||||
rv = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
to_hex_str(buf, DSAX, sizeof DSAX);
|
||||
} else {
|
||||
to_hex_str(buf, GENX, sizeof GENX);
|
||||
}
|
||||
fputs(buf, rngresp);
|
||||
fputc('\n', rngresp);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
loser:
|
||||
fclose(rngreq);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4316,7 +4552,14 @@ int main(int argc, char **argv)
|
||||
/* RNG */
|
||||
/*************/
|
||||
} else if (strcmp(argv[1], "rng") == 0) {
|
||||
do_random();
|
||||
/* argv[2]=vst|mct argv[3]=<test name>.req */
|
||||
if ( strcmp(argv[2], "vst") == 0) {
|
||||
/* Variable Seed Test */
|
||||
rng_vst(argv[3]);
|
||||
} else if (strcmp(argv[2], "mct") == 0) {
|
||||
/* Monte Carlo Test */
|
||||
rng_mct(argv[3]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
29
security/nss/cmd/fipstest/rng.sh
Normal file
29
security/nss/cmd/fipstest/rng.sh
Normal file
@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# A Bourne shell script for running the NIST RNG Validation Suite
|
||||
#
|
||||
# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
|
||||
# variables appropriately so that the fipstest command and the NSPR and NSS
|
||||
# shared libraries/DLLs are on the search path. Then run this script in the
|
||||
# directory where the REQUEST (.req) files reside. The script generates the
|
||||
# RESPONSE (.rsp) files in the same directory.
|
||||
|
||||
vst_requests="
|
||||
FIPS186_VST.req
|
||||
FIPS186_VSTGEN.req
|
||||
"
|
||||
mct_requests="
|
||||
FIPS186_MCT.req
|
||||
FIPS186_MCTGEN.req
|
||||
"
|
||||
|
||||
for request in $vst_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest rng vst $request > $response
|
||||
done
|
||||
for request in $mct_requests; do
|
||||
response=`echo $request | sed -e "s/req/rsp/"`
|
||||
echo $request $response
|
||||
fipstest rng mct $request > $response
|
||||
done
|
Loading…
Reference in New Issue
Block a user