Constant-time RSA [sync with mainstream].
authorAndy Polyakov <appro@openssl.org>
Fri, 27 May 2005 08:12:44 +0000 (08:12 +0000)
committerAndy Polyakov <appro@openssl.org>
Fri, 27 May 2005 08:12:44 +0000 (08:12 +0000)
Submitted by: bodo

fips/fipshashes.c
fips/rsa/fips_rsa_eay.c

index 8a7c1745e165089e4ca935ec0ebc63959aa3d924..a42276a423e553eb0c2f9a0e8cfc505ca55dc013 100644 (file)
@@ -14,14 +14,14 @@ const char * const FIPS_source_hashes[] = {
 "HMAC-SHA1(des/fips_des_locl.h)= e008da40dc6913e374edd66a20d44e1752f00583",
 "HMAC-SHA1(dh/fips_dh_check.c)= 63347e2007e224381d4a7b6d871633889de72cf3",
 "HMAC-SHA1(dh/fips_dh_gen.c)= 93fe69b758ca9d70d70cda1c57fff4eb5c668e85",
-"HMAC-SHA1(dh/fips_dh_key.c)= 0b810d411090abd6b676a7ca730c35362fbd04a4",
+"HMAC-SHA1(dh/fips_dh_key.c)= cd45eda7647067117adb8e80b27c3b6b34d79155",
 "HMAC-SHA1(dsa/fips_dsa_ossl.c)= ee0fbfd18d6b67a40f9a3716e6b890a487b0bbd4",
 "HMAC-SHA1(dsa/fips_dsa_gen.c)= 78c879484fd849312ca4828b957df3842b70efc0",
 "HMAC-SHA1(dsa/fips_dsa_selftest.c)= 7c2ba8d82feda2aadc8b769a3b6c4c25a6356e01",
 "HMAC-SHA1(rand/fips_rand.c)= 7e3964447a81cfe4e75df981827d14a5fe0c2923",
 "HMAC-SHA1(rand/fips_rand.h)= bf009ea8963e79b1e414442ede9ae7010a03160b",
 "HMAC-SHA1(rand/fips_rand_selftest.c)= d9c8985e08feecefafe667ad0119d444b42f807c",
-"HMAC-SHA1(rsa/fips_rsa_eay.c)= 2596773a7af8f037427217b79f56858296961d66",
+"HMAC-SHA1(rsa/fips_rsa_eay.c)= 5a7967745033e29b67f552ca77f9150f7352fa1c",
 "HMAC-SHA1(rsa/fips_rsa_gen.c)= af83b857d2be13d59e7f1516e6b1a25edd6369c3",
 "HMAC-SHA1(rsa/fips_rsa_selftest.c)= a9dc47bd1001f795d1565111d26433c300101e06",
 "HMAC-SHA1(sha/fips_sha1dgst.c)= 26e529d630b5e754b4a29bd1bb697e991e7fdc04",
index 7613042ed80413a01e601a39f9d485341f11135a..69838f4119c4f4b4c5f755d89ee2346482aedd35 100644 (file)
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
 
 #include <stdio.h>
 #include <openssl/err.h>
@@ -322,10 +375,22 @@ static int RSA_eay_private_encrypt(FIPS_RSA_SIZE_T flen, const unsigned char *fr
                (rsa->dmp1 != NULL) &&
                (rsa->dmq1 != NULL) &&
                (rsa->iqmp != NULL)) )
-               { if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; }
+               { 
+               if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err;
+               }
        else
                {
-               if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL)) goto err;
+               BIGNUM local_d;
+               BIGNUM *d = NULL;
+               
+               if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
+                       {
+                       d = &local_d;
+                       BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
+                       }
+               else
+                       d = rsa->d;
+               if (!rsa->meth->bn_mod_exp(&ret,&f,d,rsa->n,ctx,NULL)) goto err;
                }
 
        if (blinding)
@@ -435,10 +500,22 @@ static int RSA_eay_private_decrypt(FIPS_RSA_SIZE_T flen, const unsigned char *fr
                (rsa->dmp1 != NULL) &&
                (rsa->dmq1 != NULL) &&
                (rsa->iqmp != NULL)) )
-               { if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; }
+               {
+               if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err;
+               }
        else
                {
-               if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL))
+               BIGNUM local_d;
+               BIGNUM *d = NULL;
+               
+               if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
+                       {
+                       d = &local_d;
+                       BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
+                       }
+               else
+                       d = rsa->d;
+               if (!rsa->meth->bn_mod_exp(&ret,&f,d,rsa->n,ctx,NULL))
                        goto err;
                }
 
@@ -569,6 +646,8 @@ err:
 static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
        {
        BIGNUM r1,m1,vrfy;
+       BIGNUM local_dmp1, local_dmq1;
+       BIGNUM *dmp1, *dmq1;
        int ret=0;
        BN_CTX *ctx;
 
@@ -577,7 +656,6 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
        BN_init(&vrfy);
        if ((ctx=BN_CTX_new()) == NULL) goto err;
 
-
        if (rsa->flags & RSA_FLAG_CACHE_PRIVATE)
                {
                if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p,
@@ -589,11 +667,25 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
                }
 
        if (!BN_mod(&r1,I,rsa->q,ctx)) goto err;
-       if (!rsa->meth->bn_mod_exp(&m1,&r1,rsa->dmq1,rsa->q,ctx,
+       if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
+               {
+               dmq1 = &local_dmq1;
+               BN_with_flags(dmq1, rsa->dmq1, BN_FLG_EXP_CONSTTIME);
+               }
+       else
+               dmq1 = rsa->dmq1;
+       if (!rsa->meth->bn_mod_exp(&m1,&r1,dmq1,rsa->q,ctx,
                rsa->_method_mod_q)) goto err;
 
        if (!BN_mod(&r1,I,rsa->p,ctx)) goto err;
-       if (!rsa->meth->bn_mod_exp(r0,&r1,rsa->dmp1,rsa->p,ctx,
+       if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
+               {
+               dmp1 = &local_dmp1;
+               BN_with_flags(dmp1, rsa->dmp1, BN_FLG_EXP_CONSTTIME);
+               }
+       else
+               dmp1 = rsa->dmp1;
+       if (!rsa->meth->bn_mod_exp(r0,&r1,dmp1,rsa->p,ctx,
                rsa->_method_mod_p)) goto err;
 
        if (!BN_sub(r0,r0,&m1)) goto err;
@@ -628,10 +720,23 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa)
                if (vrfy.neg)
                        if (!BN_add(&vrfy, &vrfy, rsa->n)) goto err;
                if (!BN_is_zero(&vrfy))
+                       {
                        /* 'I' and 'vrfy' aren't congruent mod n. Don't leak
                         * miscalculated CRT output, just do a raw (slower)
                         * mod_exp and return that instead. */
-                       if (!rsa->meth->bn_mod_exp(r0,I,rsa->d,rsa->n,ctx,NULL)) goto err;
+
+                       BIGNUM local_d;
+                       BIGNUM *d = NULL;
+               
+                       if (!(rsa->flags & RSA_FLAG_NO_EXP_CONSTTIME))
+                               {
+                               d = &local_d;
+                               BN_with_flags(d, rsa->d, BN_FLG_EXP_CONSTTIME);
+                               }
+                       else
+                               d = rsa->d;
+                       if (!rsa->meth->bn_mod_exp(r0,I,d,rsa->n,ctx,NULL)) goto err;
+                       }
                }
        ret=1;
 err: