diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2011-01-26 15:37:41 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2011-01-26 15:37:41 +0000 |
commit | c553721e8ba2a79c9ee14bf17814271ce1f33d9e (patch) | |
tree | 88e6aee60d78b8c534ea559f1106dddaa4229e4c /crypto/rsa/rsa_gen.c | |
parent | 1588a3cae72e60071f1f8a89dbd1356bc08581fc (diff) | |
download | openssl-c553721e8ba2a79c9ee14bf17814271ce1f33d9e.tar.gz |
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.
Diffstat (limited to 'crypto/rsa/rsa_gen.c')
-rw-r--r-- | crypto/rsa/rsa_gen.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/crypto/rsa/rsa_gen.c b/crypto/rsa/rsa_gen.c index 767f7ab682..b8676ad020 100644 --- a/crypto/rsa/rsa_gen.c +++ b/crypto/rsa/rsa_gen.c @@ -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) |