FIPS mode RSA changes:

Check for selftest failures.

Pairwise consistency test for RSA key generation.

Use some EVP macros instead of EVP functions.

Use minimal FIPS EVP where needed.
This commit is contained in:
Dr. Stephen Henson
2011-01-26 15:37:41 +00:00
parent 1588a3cae7
commit c553721e8b
8 changed files with 212 additions and 15 deletions

View File

@@ -68,6 +68,77 @@
#include <openssl/bn.h>
#include <openssl/rsa.h>
#ifdef OPENSSL_FIPS
#include <openssl/fips.h>
#include <openssl/evp.h>
static int fips_rsa_pairwise_fail = 0;
void FIPS_corrupt_rsa_keygen(void)
{
fips_rsa_pairwise_fail = 1;
}
int fips_check_rsa(RSA *rsa)
{
const unsigned char tbs[] = "RSA Pairwise Check Data";
unsigned char *ctbuf = NULL, *ptbuf = NULL;
int len, ret = 0;
EVP_PKEY pk;
pk.type = EVP_PKEY_RSA;
pk.pkey.rsa = rsa;
/* Perform pairwise consistency signature test */
if (!fips_pkey_signature_test(&pk, tbs, -1,
NULL, 0, EVP_sha1(), RSA_PKCS1_PADDING, NULL)
|| !fips_pkey_signature_test(&pk, tbs, -1,
NULL, 0, EVP_sha1(), RSA_X931_PADDING, NULL)
|| !fips_pkey_signature_test(&pk, tbs, -1,
NULL, 0, EVP_sha1(), RSA_PKCS1_PSS_PADDING, NULL))
goto err;
/* Now perform pairwise consistency encrypt/decrypt test */
ctbuf = OPENSSL_malloc(RSA_size(rsa));
if (!ctbuf)
goto err;
len = RSA_public_encrypt(sizeof(tbs) - 1, tbs, ctbuf, rsa, RSA_PKCS1_PADDING);
if (len <= 0)
goto err;
/* Check ciphertext doesn't match plaintext */
if ((len == (sizeof(tbs) - 1)) && !memcmp(tbs, ctbuf, len))
goto err;
ptbuf = OPENSSL_malloc(RSA_size(rsa));
if (!ptbuf)
goto err;
len = RSA_private_decrypt(len, ctbuf, ptbuf, rsa, RSA_PKCS1_PADDING);
if (len != (sizeof(tbs) - 1))
goto err;
if (memcmp(ptbuf, tbs, len))
goto err;
ret = 1;
if (!ptbuf)
goto err;
err:
if (ret == 0)
{
fips_set_selftest_fail();
FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED);
}
if (ctbuf)
OPENSSL_free(ctbuf);
if (ptbuf)
OPENSSL_free(ptbuf);
return ret;
}
#endif
static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb);
/* NB: this wrapper would normally be placed in rsa_lib.c and the static
@@ -90,6 +161,20 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
int bitsp,bitsq,ok= -1,n=0;
BN_CTX *ctx=NULL;
#ifdef OPENSSL_FIPS
if(FIPS_selftest_failed())
{
FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_FIPS_SELFTEST_FAILED);
return 0;
}
if (FIPS_mode() && (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
{
FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_KEY_TOO_SHORT);
return 0;
}
#endif
ctx=BN_CTX_new();
if (ctx == NULL) goto err;
BN_CTX_start(ctx);
@@ -201,6 +286,14 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
p = rsa->p;
if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err;
#ifdef OPENSSL_FIPS
if (fips_rsa_pairwise_fail)
BN_add_word(rsa->n, 1);
if(!fips_check_rsa(rsa))
goto err;
#endif
ok=1;
err:
if (ok == -1)