/* * Generates new random bytes and advances the internal prng state. * additional bytes are only used in algorithm testing. * * This function is specified in NIST SP 800-90 section 10.1.1.4 */ static SECStatus prng_generateNewBytes(RNGContext *rng, PRUint8 *returned_bytes, unsigned int no_of_returned_bytes, const PRUint8 *additional_input, unsigned int additional_input_len) { PRUint8 H[SHA256_LENGTH]; /* both H and w since they * aren't used concurrently */ unsigned int carry; int k1, k2; if (!rng->isValid) { PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } /* This code only triggers during tests, normal * prng operation does not use additional_input */ if (additional_input){ SHA256Context ctx; /* NIST SP 800-90 defines two temporaries in their calculations, * w and H. These temporaries are the same lengths, and used * at different times, so we use the following macro to collapse * them to the same variable, but keeping their unique names for * easy comparison to the spec */ #define w H rng->V_type = prngAdditionalDataType; SHA256_Begin(&ctx); SHA256_Update(&ctx, rng->V_Data, sizeof rng->V_Data); SHA256_Update(&ctx, additional_input, additional_input_len); SHA256_End(&ctx, w, NULL, sizeof w); PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), w, sizeof w) PORT_Memset(w, 0, sizeof w); #undef w } if (no_of_returned_bytes == SHA256_LENGTH) { /* short_cut to hashbuf and save a copy and a clear */ SHA256_HashBuf(returned_bytes, V(rng), VSize(rng) ); } else { prng_Hashgen(rng, returned_bytes, no_of_returned_bytes); } /* advance our internal state... */ rng->V_type = prngGenerateByteType; SHA256_HashBuf(H, rng->V_Data, sizeof rng->V_Data); PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), H, sizeof H) PRNG_ADD_BITS(V(rng), VSize(rng), rng->C, sizeof rng->C); PRNG_ADD_BITS_AND_CARRY(V(rng), VSize(rng), rng->reseed_counter, sizeof rng->reseed_counter) PRNG_ADD_CARRY_ONLY(rng->reseed_counter,(sizeof rng->reseed_counter)-1, 1); /* continuous rng check */ if (memcmp(V(rng), rng->oldV, sizeof rng->oldV) == 0) { rng->isValid = PR_FALSE; PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); return SECFailure; } PORT_Memcpy(rng->oldV, V(rng), sizeof rng->oldV); return SECSuccess; }
/* * Test the softoken RSA_HashSign and RSH_HashCheckSign. */ static SECStatus sftk_fips_RSA_PowerUpSigSelfTest(HASH_HashType shaAlg, NSSLOWKEYPublicKey *rsa_public_key, NSSLOWKEYPrivateKey *rsa_private_key, const unsigned char *rsa_known_msg, const unsigned int rsa_kmsg_length, const unsigned char *rsa_known_signature) { SECOidTag shaOid; /* SHA OID */ unsigned char sha[HASH_LENGTH_MAX]; /* SHA digest */ unsigned int shaLength = 0; /* length of SHA */ unsigned int rsa_bytes_signed; unsigned char rsa_computed_signature[FIPS_RSA_SIGNATURE_LENGTH]; SECStatus rv; if (shaAlg == HASH_AlgSHA1) { if (SHA1_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) != SECSuccess) { goto loser; } shaLength = SHA1_LENGTH; shaOid = SEC_OID_SHA1; } else if (shaAlg == HASH_AlgSHA256) { if (SHA256_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) != SECSuccess) { goto loser; } shaLength = SHA256_LENGTH; shaOid = SEC_OID_SHA256; } else if (shaAlg == HASH_AlgSHA384) { if (SHA384_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) != SECSuccess) { goto loser; } shaLength = SHA384_LENGTH; shaOid = SEC_OID_SHA384; } else if (shaAlg == HASH_AlgSHA512) { if (SHA512_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) != SECSuccess) { goto loser; } shaLength = SHA512_LENGTH; shaOid = SEC_OID_SHA512; } else { goto loser; } /*************************************************/ /* RSA Single-Round Known Answer Signature Test. */ /*************************************************/ /* Perform RSA signature with the RSA private key. */ rv = RSA_HashSign(shaOid, rsa_private_key, rsa_computed_signature, &rsa_bytes_signed, FIPS_RSA_SIGNATURE_LENGTH, sha, shaLength); if ((rv != SECSuccess) || (rsa_bytes_signed != FIPS_RSA_SIGNATURE_LENGTH) || (PORT_Memcmp(rsa_computed_signature, rsa_known_signature, FIPS_RSA_SIGNATURE_LENGTH) != 0)) { goto loser; } /****************************************************/ /* RSA Single-Round Known Answer Verification Test. */ /****************************************************/ /* Perform RSA verification with the RSA public key. */ rv = RSA_HashCheckSign(shaOid, rsa_public_key, rsa_computed_signature, rsa_bytes_signed, sha, shaLength); if (rv != SECSuccess) { goto loser; } return (SECSuccess); loser: return (SECFailure); }