aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/rsa/rsa_gen.c
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2011-01-26 15:37:41 +0000
committerDr. Stephen Henson <steve@openssl.org>2011-01-26 15:37:41 +0000
commitc553721e8ba2a79c9ee14bf17814271ce1f33d9e (patch)
tree88e6aee60d78b8c534ea559f1106dddaa4229e4c /crypto/rsa/rsa_gen.c
parent1588a3cae72e60071f1f8a89dbd1356bc08581fc (diff)
downloadopenssl-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.c93
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)