318970 RSA FIPS tests r=wan-teh sr=bobRelyea

This commit is contained in:
glen.beasley%sun.com 2006-01-31 00:49:02 +00:00
Родитель 26b41400b8
Коммит e3acf26812
2 изменённых файлов: 493 добавлений и 0 удалений

Просмотреть файл

@ -45,7 +45,11 @@
#include "secoidt.h" #include "secoidt.h"
#include "keythi.h" #include "keythi.h"
#include "ec.h" #include "ec.h"
#include "hasht.h"
#include "lowkeyi.h"
#include "softoken.h"
#include "pqgutil.h" #include "pqgutil.h"
#if 0 #if 0
#include "../../lib/freebl/mpi/mpi.h" #include "../../lib/freebl/mpi/mpi.h"
#endif #endif
@ -58,6 +62,9 @@ EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams);
#define ENCRYPT 1 #define ENCRYPT 1
#define DECRYPT 0 #define DECRYPT 0
#define BYTE unsigned char #define BYTE unsigned char
#define DEFAULT_RSA_PUBLIC_EXPONENT 0x10001
#define RSA_MAX_TEST_MODULUS_BITS 4096
#define RSA_MAX_TEST_MODULUS_BYTES RSA_MAX_TEST_MODULUS_BITS/8
SECStatus SECStatus
hex_from_2char(const unsigned char *c2, unsigned char *byteval) hex_from_2char(const unsigned char *c2, unsigned char *byteval)
@ -3741,6 +3748,459 @@ loser:
} }
} }
/*
* Perform the RSA Signature Generation Test.
*
* reqfn is the pathname of the REQUEST file.
*
* The output RESPONSE file is written to stdout.
*/
void
rsa_siggen_test(char *reqfn)
{
char buf[2*RSA_MAX_TEST_MODULUS_BYTES+1];
/* buf holds one line from the input REQUEST file
* or to the output RESPONSE file.
* 2x for HEX output + 1 for \n
*/
FILE *rsareq; /* input stream from the REQUEST file */
FILE *rsaresp; /* output stream to the RESPONSE file */
int i, j;
unsigned char sha[HASH_LENGTH_MAX]; /* SHA digest */
unsigned int shaLength = 0; /* length of SHA */
HASH_HashType shaAlg = HASH_AlgNULL; /* type of SHA Alg */
int modulus; /* the Modulus size */
int publicExponent = DEFAULT_RSA_PUBLIC_EXPONENT;
SECItem pe = {0, 0, 0 };
unsigned char pubEx[4];
int peCount = 0;
RSAPrivateKey *rsaBlapiPrivKey = NULL; /* holds RSA private and
* public keys */
RSAPublicKey *rsaBlapiPublicKey = NULL; /* hold RSA public key */
rsareq = fopen(reqfn, "r");
rsaresp = stdout;
/* calculate the exponent */
for (i=0; i < 4; i++) {
if (peCount || (publicExponent & ((unsigned long)0xff000000L >>
(i*8)))) {
pubEx[peCount] = (unsigned char)((publicExponent >>
(3-i)*8) & 0xff);
peCount++;
}
}
pe.len = peCount;
pe.data = &pubEx[0];
pe.type = siBuffer;
while (fgets(buf, sizeof buf, rsareq) != NULL) {
/* a comment or blank line */
if (buf[0] == '#' || buf[0] == '\n') {
fputs(buf, rsaresp);
continue;
}
/* [mod = ...] */
if (buf[0] == '[') {
if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
goto loser;
}
if (modulus > RSA_MAX_TEST_MODULUS_BITS) {
fprintf(rsaresp,"ERROR: modulus greater than test maximum\n");
goto loser;
}
fputs(buf, rsaresp);
if (rsaBlapiPrivKey != NULL) {
PORT_FreeArena(rsaBlapiPrivKey->arena, PR_TRUE);
rsaBlapiPrivKey = NULL;
rsaBlapiPublicKey = NULL;
}
rsaBlapiPrivKey = RSA_NewKey(modulus, &pe);
if (rsaBlapiPrivKey == NULL) {
fprintf(rsaresp, "Error unable to create RSA key\n");
goto loser;
}
to_hex_str(buf, rsaBlapiPrivKey->modulus.data,
rsaBlapiPrivKey->modulus.len);
fprintf(rsaresp, "n = %s\n\n", buf);
to_hex_str(buf, rsaBlapiPrivKey->publicExponent.data,
rsaBlapiPrivKey->publicExponent.len);
fprintf(rsaresp, "e = %s\n", buf);
/* convert private key to public key. Memory
* is freed with private key's arena */
rsaBlapiPublicKey = (RSAPublicKey *)PORT_ArenaAlloc(
rsaBlapiPrivKey->arena,
sizeof(RSAPublicKey));
rsaBlapiPublicKey->modulus.len = rsaBlapiPrivKey->modulus.len;
rsaBlapiPublicKey->modulus.data = rsaBlapiPrivKey->modulus.data;
rsaBlapiPublicKey->publicExponent.len =
rsaBlapiPrivKey->publicExponent.len;
rsaBlapiPublicKey->publicExponent.data =
rsaBlapiPrivKey->publicExponent.data;
continue;
}
/* SHAAlg = ... */
if (strncmp(buf, "SHAAlg", 6) == 0) {
i = 6;
while (isspace(buf[i]) || buf[i] == '=') {
i++;
}
/* set the SHA Algorithm */
if (strncmp(&buf[i], "SHA1", 4) == 0) {
shaAlg = HASH_AlgSHA1;
} else if (strncmp(&buf[i], "SHA256", 6)) {
shaAlg = HASH_AlgSHA256;
} else if (strncmp(&buf[i], "SHA384", 6)) {
shaAlg = HASH_AlgSHA384;
} else if (strncmp(&buf[i], "SHA512", 6)) {
shaAlg = HASH_AlgSHA512;
} else {
fprintf(rsaresp, "ERROR: Unable to find SHAAlg type");
goto loser;
}
fputs(buf, rsaresp);
continue;
}
/* Msg = ... */
if (strncmp(buf, "Msg", 3) == 0) {
unsigned char msg[128]; /* MAX msg 128 */
unsigned int rsa_bytes_signed;
unsigned char rsa_computed_signature[RSA_MAX_TEST_MODULUS_BYTES];
SECStatus rv = SECFailure;
NSSLOWKEYPublicKey * rsa_public_key;
NSSLOWKEYPrivateKey * rsa_private_key;
NSSLOWKEYPrivateKey low_RSA_private_key = { NULL,
NSSLOWKEYRSAKey, };
NSSLOWKEYPublicKey low_RSA_public_key = { NULL,
NSSLOWKEYRSAKey, };
low_RSA_private_key.u.rsa = *rsaBlapiPrivKey;
low_RSA_public_key.u.rsa = *rsaBlapiPublicKey;
rsa_private_key = &low_RSA_private_key;
rsa_public_key = &low_RSA_public_key;
memset(sha, 0, sizeof sha);
memset(msg, 0, sizeof msg);
rsa_bytes_signed = 0;
memset(rsa_computed_signature, 0, sizeof rsa_computed_signature);
i = 3;
while (isspace(buf[i]) || buf[i] == '=') {
i++;
}
for (j=0; isxdigit(buf[i]) && j >= sizeof(msg); i+=2,j++) {
hex_from_2char(&buf[i], &msg[j]);
}
if (shaAlg == HASH_AlgSHA1) {
if (SHA1_HashBuf(sha, msg, j) != SECSuccess) {
fprintf(rsaresp, "ERROR: Unable to generate SHA1");
goto loser;
}
shaLength = SHA1_LENGTH;
} else if (shaAlg == HASH_AlgSHA256) {
if (SHA256_HashBuf(sha, msg, j) != SECSuccess) {
fprintf(rsaresp, "ERROR: Unable to generate SHA256");
goto loser;
}
shaLength = SHA256_LENGTH;
} else if (shaAlg == HASH_AlgSHA384) {
if (SHA384_HashBuf(sha, msg, j) != SECSuccess) {
fprintf(rsaresp, "ERROR: Unable to generate SHA384");
goto loser;
}
shaLength = SHA384_LENGTH;
} else if (shaAlg == HASH_AlgSHA512) {
if (SHA512_HashBuf(sha, msg, j) != SECSuccess) {
fprintf(rsaresp, "ERROR: Unable to generate SHA512");
goto loser;
}
shaLength = SHA512_LENGTH;
} else {
fprintf(rsaresp, "ERROR: SHAAlg not defined.");
goto loser;
}
/* Perform RSA signature with the RSA private key. */
rv = RSA_Sign( rsa_private_key, rsa_computed_signature,
&rsa_bytes_signed,
nsslowkey_PrivateModulusLen(rsa_private_key),
sha,
shaLength);
if( rv != SECSuccess ) {
fprintf(rsaresp, "ERROR: RSA_Sign failed");
goto loser;
}
/* Output the signature */
fputs(buf, rsaresp);
to_hex_str(buf, rsa_computed_signature, rsa_bytes_signed);
fprintf(rsaresp, "S = %s\n", buf);
/* Perform RSA verification with the RSA public key. */
rv = RSA_CheckSign( rsa_public_key,
rsa_computed_signature,
rsa_bytes_signed,
sha,
shaLength);
if( rv != SECSuccess ) {
fprintf(rsaresp, "ERROR: RSA_CheckSign failed");
goto loser;
}
continue;
}
}
loser:
fclose(rsareq);
if (rsaBlapiPrivKey != NULL) {
/* frees private and public key */
PORT_FreeArena(rsaBlapiPrivKey->arena, PR_TRUE);
rsaBlapiPrivKey = NULL;
rsaBlapiPublicKey = NULL;
}
}
/*
* Perform the RSA Signature Verification Test.
*
* reqfn is the pathname of the REQUEST file.
*
* The output RESPONSE file is written to stdout.
*/
void
rsa_sigver_test(char *reqfn)
{
char buf[2*RSA_MAX_TEST_MODULUS_BYTES+7];
/* buf holds one line from the input REQUEST file
* or to the output RESPONSE file.
* s = 2x for HEX output + 1 for \n
*/
FILE *rsareq; /* input stream from the REQUEST file */
FILE *rsaresp; /* output stream to the RESPONSE file */
int i, j;
unsigned char sha[HASH_LENGTH_MAX]; /* SHA digest */
unsigned int shaLength; /* actual length of the digest */
HASH_HashType shaAlg = HASH_AlgNULL;
int modulus; /* the Modulus size */
unsigned char signature[513]; /* largest signature size + '\n' */
unsigned int signatureLength; /* actual length of the signature */
PRBool keyvalid = PR_TRUE;
RSAPublicKey rsaBlapiPublicKey; /* hold RSA public key */
rsareq = fopen(reqfn, "r");
rsaresp = stdout;
memset(&rsaBlapiPublicKey, 0, sizeof(RSAPublicKey));
while (fgets(buf, sizeof buf, rsareq) != NULL) {
/* a comment or blank line */
if (buf[0] == '#' || buf[0] == '\n') {
fputs(buf, rsaresp);
continue;
}
/* [Mod = ...] */
if (buf[0] == '[') {
unsigned int flen; /* length in bytes of the field size */
if (rsaBlapiPublicKey.modulus.data) { /* n */
SECITEM_ZfreeItem(&rsaBlapiPublicKey.modulus, PR_FALSE);
}
if (rsaBlapiPublicKey.publicExponent.data) { /* e */
SECITEM_ZfreeItem(&rsaBlapiPublicKey.publicExponent, PR_FALSE);
}
if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
goto loser;
}
if (modulus > RSA_MAX_TEST_MODULUS_BITS) {
fprintf(rsaresp,"ERROR: modulus greater than test maximum\n");
goto loser;
}
fputs(buf, rsaresp);
signatureLength = flen = modulus/8;
SECITEM_AllocItem(NULL, &rsaBlapiPublicKey.modulus, flen);
if (rsaBlapiPublicKey.modulus.data == NULL) {
goto loser;
}
SECITEM_AllocItem(NULL, &rsaBlapiPublicKey.publicExponent, flen);
if (rsaBlapiPublicKey.publicExponent.data == NULL) {
goto loser;
}
continue;
}
/* n = ... modulus */
if (buf[0] == 'n') {
i = 1;
while (isspace(buf[i]) || buf[i] == '=') {
i++;
}
keyvalid = from_hex_str(&rsaBlapiPublicKey.modulus.data[0],
rsaBlapiPublicKey.modulus.len,
&buf[i]);
if (!keyvalid) {
fprintf(rsaresp, "ERROR: rsa_sigver n not valid.\n");
goto loser;
}
fputs(buf, rsaresp);
continue;
}
/* SHAAlg = ... */
if (strncmp(buf, "SHAAlg", 6) == 0) {
i = 6;
while (isspace(buf[i]) || buf[i] == '=') {
i++;
}
/* set the SHA Algorithm */
if (strncmp(&buf[i], "SHA1", 4) == 0) {
shaAlg = HASH_AlgSHA1;
} else if (strncmp(&buf[i], "SHA256", 6)) {
shaAlg = HASH_AlgSHA256;
} else if (strncmp(&buf[i], "SHA384", 6)) {
shaAlg = HASH_AlgSHA384;
} else if (strncmp(&buf[i], "SHA512", 6)) {
shaAlg = HASH_AlgSHA512;
} else {
fprintf(rsaresp, "ERROR: Unable to find SHAAlg type");
goto loser;
}
fputs(buf, rsaresp);
continue;
}
/* e = ... public Key */
if (buf[0] == 'e') {
i = 1;
while (isspace(buf[i]) || buf[i] == '=') {
i++;
}
if (!from_hex_str(&rsaBlapiPublicKey.publicExponent.data[0],
rsaBlapiPublicKey.publicExponent.len, &buf[i])) {
goto loser;
}
fputs(buf, rsaresp);
continue;
}
/* Msg = ... */
if (strncmp(buf, "Msg", 3) == 0) {
unsigned char msg[128]; /* MAX msg 128 */
memset(sha, 0, sizeof sha);
memset(msg, 0, sizeof msg);
i = 3;
while (isspace(buf[i]) || buf[i] == '=') {
i++;
}
for (j=0; isxdigit(buf[i]) && j >= sizeof(msg); i+=2,j++) {
hex_from_2char(&buf[i], &msg[j]);
}
if (shaAlg == HASH_AlgSHA1) {
if (SHA1_HashBuf(sha, msg, j) != SECSuccess) {
fprintf(rsaresp, "ERROR: Unable to generate SHA1");
goto loser;
}
shaLength = SHA1_LENGTH;
} else if (shaAlg == HASH_AlgSHA256) {
if (SHA256_HashBuf(sha, msg, j) != SECSuccess) {
fprintf(rsaresp, "ERROR: Unable to generate SHA256");
goto loser;
}
shaLength = SHA256_LENGTH;
} else if (shaAlg == HASH_AlgSHA384) {
if (SHA384_HashBuf(sha, msg, j) != SECSuccess) {
fprintf(rsaresp, "ERROR: Unable to generate SHA384");
goto loser;
}
shaLength = SHA384_LENGTH;
} else if (shaAlg == HASH_AlgSHA512) {
if (SHA512_HashBuf(sha, msg, j) != SECSuccess) {
fprintf(rsaresp, "ERROR: Unable to generate SHA512");
goto loser;
}
shaLength = SHA512_LENGTH;
} else {
fprintf(rsaresp, "ERROR: SHAAlg not defined.");
goto loser;
}
fputs(buf, rsaresp);
continue;
}
/* S = ... */
if (buf[0] == 'S') {
SECStatus rv = SECFailure;
NSSLOWKEYPublicKey * rsa_public_key;
NSSLOWKEYPublicKey low_RSA_public_key = { NULL,
NSSLOWKEYRSAKey, };
/* convert to a low RSA public key */
low_RSA_public_key.u.rsa = rsaBlapiPublicKey;
rsa_public_key = &low_RSA_public_key;
memset(signature, 0, sizeof(signature));
i = 1;
while (isspace(buf[i]) || buf[i] == '=') {
i++;
}
if (!from_hex_str(signature,
signatureLength, &buf[i])) {
goto loser;
}
fputs(buf, rsaresp);
/* Perform RSA verification with the RSA public key. */
rv = RSA_CheckSign( rsa_public_key,
signature,
signatureLength,
sha,
shaLength);
if( rv == SECSuccess ) {
fputs("Result = P\n", rsaresp);
} else {
fputs("Result = F\n", rsaresp);
}
continue;
}
}
loser:
fclose(rsareq);
if (rsaBlapiPublicKey.modulus.data) { /* n */
SECITEM_ZfreeItem(&rsaBlapiPublicKey.modulus, PR_FALSE);
}
if (rsaBlapiPublicKey.publicExponent.data) { /* e */
SECITEM_ZfreeItem(&rsaBlapiPublicKey.publicExponent, PR_FALSE);
}
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
if (argc < 2) exit (-1); if (argc < 2) exit (-1);
@ -3793,6 +4253,19 @@ int main(int argc, char **argv)
} else if (strcmp(argv[1], "sha") == 0) { } else if (strcmp(argv[1], "sha") == 0) {
sha_test(argv[2]); sha_test(argv[2]);
/*************/ /*************/
/* RSA */
/*************/
} else if (strcmp(argv[1], "rsa") == 0) {
/* argv[2]=siggen|sigver */
/* argv[3]=<test name>.req */
if (strcmp(argv[2], "siggen") == 0) {
/* Signature Generation Test */
rsa_siggen_test(argv[3]);
} else if (strcmp(argv[2], "sigver") == 0) {
/* Signature Verification Test */
rsa_sigver_test(argv[3]);
}
/*************/
/* HMAC */ /* HMAC */
/*************/ /*************/
} else if (strcmp(argv[1], "hmac") == 0) { } else if (strcmp(argv[1], "hmac") == 0) {

Просмотреть файл

@ -0,0 +1,20 @@
#!/bin/sh
#
# A Bourne shell script for running the NIST RSA Validation System
#
# 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.
request=SigGen15.req
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest dsa siggen $request > $response
request=SigVer15.req
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest dsa sigver $request > $response