]> granicus.if.org Git - openssl/commitdiff
Implement fixed-window exponentiation to mitigate hyper-threading
authorBodo Möller <bodo@openssl.org>
Mon, 16 May 2005 01:26:08 +0000 (01:26 +0000)
committerBodo Möller <bodo@openssl.org>
Mon, 16 May 2005 01:26:08 +0000 (01:26 +0000)
timing attacks.

BN_FLG_EXP_CONSTTIME requests this algorithm, and this done by default for
RSA/DSA/DH private key computations unless
RSA_FLAG_NO_EXP_CONSTTIME/DSA_FLAG_NO_EXP_CONSTTIME/
DH_FLAG_NO_EXP_CONSTTIME is set.

Submitted by: Matthew D Wood
Reviewed by: Bodo Moeller

20 files changed:
CHANGES
apps/speed.c
crypto/bn/bn.h
crypto/bn/bn_err.c
crypto/bn/bn_exp.c
crypto/bn/bn_lcl.h
crypto/bn/bntest.c
crypto/bn/expspeed.c
crypto/bn/exptest.c
crypto/dh/dh.h
crypto/dh/dh_key.c
crypto/dh/dhtest.c
crypto/dsa/dsa.h
crypto/dsa/dsa_key.c
crypto/dsa/dsa_ossl.c
crypto/dsa/dsatest.c
crypto/rsa/rsa.h
crypto/rsa/rsa_eay.c
crypto/rsa/rsa_test.c
util/libeay.num

diff --git a/CHANGES b/CHANGES
index 82b24f052d7b35479aa829483eb14eb3c8f712d1..b87152a8e78d6320ff521d831cf7bd710acf2e7c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,21 @@
 
  Changes between 0.9.7g and 0.9.7h  [XX xxx XXXX]
 
+  *) Make a new fixed-window mod_exp implementation the default for
+     RSA, DSA, and DH private-key operations to mitigate the
+     hyper-threading timing attacks pointed out by Colin Percival
+     (http://www.daemonology.net/hyperthreading-considered-harmful/),
+     and potential related attacks.
+
+     BN_mod_exp_mont_consttime() is the new exponentiation implementation,
+     and this is automatically used by BN_mod_exp_mont() if the new flag
+     BN_FLG_EXP_CONSTTIME is set for the exponent.  RSA, DSA, and DH
+     will use this BN flag for private exponents unless the flag
+     RSA_FLAG_NO_EXP_CONSTTIME, DSA_FLAG_NO_EXP_CONSTTIME, or
+     DH_FLAG_NO_EXP_CONSTTIME, respectively, is set.
+
+     [Matthew D Wood (Intel Corp), with some changes by Bodo Moeller]
+
   *) Change the client implementation for SSLv23_method() and
      SSLv23_client_method() so that is uses the SSL 3.0/TLS 1.0
      Client Hello message format if the SSL_OP_NO_SSLv2 option is set.
index 5ed510ced69b94ca505b41824e28f0a06a10ea6d..2fc327c375c483ab2ef429e87c1fbfe85c1b79ca 100644 (file)
@@ -1706,7 +1706,7 @@ show_res:
                                k,rsa_bits[k],rsa_results[k][0],
                                rsa_results[k][1]);
                else
-                       fprintf(stdout,"rsa %4u bits %8.4fs %8.4fs %8.1f %8.1f\n",
+                       fprintf(stdout,"rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
                                rsa_bits[k],rsa_results[k][0],rsa_results[k][1],
                                1.0/rsa_results[k][0],1.0/rsa_results[k][1]);
                }
@@ -1725,7 +1725,7 @@ show_res:
                        fprintf(stdout,"+F3:%u:%u:%f:%f\n",
                                k,dsa_bits[k],dsa_results[k][0],dsa_results[k][1]);
                else
-                       fprintf(stdout,"dsa %4u bits %8.4fs %8.4fs %8.1f %8.1f\n",
+                       fprintf(stdout,"dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
                                dsa_bits[k],dsa_results[k][0],dsa_results[k][1],
                                1.0/dsa_results[k][0],1.0/dsa_results[k][1]);
                }
index ad42f2df7b8ae9e0960da9bd890edd7eaa2afcc8..91674afd37d8088107b678fdedd82627dd4fa9a3 100644 (file)
@@ -225,10 +225,21 @@ extern "C" {
 
 #define BN_FLG_MALLOCED                0x01
 #define BN_FLG_STATIC_DATA     0x02
+#define BN_FLG_EXP_CONSTTIME   0x04 /* avoid leaking exponent information through timings
+                                     * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) */
 #define BN_FLG_FREE            0x8000  /* used for debuging */
 #define BN_set_flags(b,n)      ((b)->flags|=(n))
 #define BN_get_flags(b,n)      ((b)->flags&(n))
 
+#define BN_with_flags(dest,b,n)  ((dest)->d=(b)->d, \
+                                  (dest)->top=(b)->top, \
+                                  (dest)->dmax=(b)->dmax, \
+                                  (dest)->neg=(b)->neg, \
+                                  (dest)->flags=(((dest)->flags & BN_FLG_MALLOCED) \
+                                                 |  ((b)->flags & ~BN_FLG_MALLOCED) \
+                                                 |  BN_FLG_STATIC_DATA \
+                                                 |  (n)))
+
 typedef struct bignum_st
        {
        BN_ULONG *d;    /* Pointer to an array of 'BN_BITS2' bit chunks. */
@@ -378,6 +389,8 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        const BIGNUM *m,BN_CTX *ctx);
 int    BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont);
 int    BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
        const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
 int    BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1,
@@ -512,11 +525,15 @@ void ERR_load_BN_strings(void);
 #define BN_F_BN_CTX_GET                                         116
 #define BN_F_BN_CTX_NEW                                         106
 #define BN_F_BN_DIV                                     107
+#define BN_F_BN_EXP                                     123
 #define BN_F_BN_EXPAND2                                         108
 #define BN_F_BN_EXPAND_INTERNAL                                 120
 #define BN_F_BN_MOD_EXP2_MONT                           118
 #define BN_F_BN_MOD_EXP_MONT                            109
+#define BN_F_BN_MOD_EXP_MONT_CONSTTIME                  124
 #define BN_F_BN_MOD_EXP_MONT_WORD                       117
+#define BN_F_BN_MOD_EXP_RECP                            125
+#define BN_F_BN_MOD_EXP_SIMPLE                          126
 #define BN_F_BN_MOD_INVERSE                             110
 #define BN_F_BN_MOD_LSHIFT_QUICK                        119
 #define BN_F_BN_MOD_MUL_RECIPROCAL                      111
index 45c523ae2f2b3d24e8b42d1bb8f84640d04be17d..5dfac00c88ab1b5474ee92e59428f927ae606fa8 100644 (file)
@@ -79,11 +79,15 @@ static ERR_STRING_DATA BN_str_functs[]=
 {ERR_FUNC(BN_F_BN_CTX_GET),    "BN_CTX_get"},
 {ERR_FUNC(BN_F_BN_CTX_NEW),    "BN_CTX_new"},
 {ERR_FUNC(BN_F_BN_DIV),        "BN_div"},
+{ERR_FUNC(BN_F_BN_EXP),        "BN_exp"},
 {ERR_FUNC(BN_F_BN_EXPAND2),    "bn_expand2"},
 {ERR_FUNC(BN_F_BN_EXPAND_INTERNAL),    "BN_EXPAND_INTERNAL"},
 {ERR_FUNC(BN_F_BN_MOD_EXP2_MONT),      "BN_mod_exp2_mont"},
 {ERR_FUNC(BN_F_BN_MOD_EXP_MONT),       "BN_mod_exp_mont"},
+{ERR_FUNC(BN_F_BN_MOD_EXP_MONT_CONSTTIME),     "BN_mod_exp_mont_consttime"},
 {ERR_FUNC(BN_F_BN_MOD_EXP_MONT_WORD),  "BN_mod_exp_mont_word"},
+{ERR_FUNC(BN_F_BN_MOD_EXP_RECP),       "BN_mod_exp_recp"},
+{ERR_FUNC(BN_F_BN_MOD_EXP_SIMPLE),     "BN_mod_exp_simple"},
 {ERR_FUNC(BN_F_BN_MOD_INVERSE),        "BN_mod_inverse"},
 {ERR_FUNC(BN_F_BN_MOD_LSHIFT_QUICK),   "BN_mod_lshift_quick"},
 {ERR_FUNC(BN_F_BN_MOD_MUL_RECIPROCAL), "BN_mod_mul_reciprocal"},
index afdfd580fb43947dc380aa44dccd232d1cc5c5c8..9e1e88abe8d2cefd53109d9482b91797220aa0ad 100644 (file)
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ * 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
 #include "cryptlib.h"
 #include "bn_lcl.h"
 
+/* maximum precomputation table size for *variable* sliding windows */
 #define TABLE_SIZE     32
 
 /* this one works - simple but works */
@@ -121,6 +122,13 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
        int i,bits,ret=0;
        BIGNUM *v,*rr;
 
+       if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
+               {
+               /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */
+               BNerr(BN_F_BN_EXP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+               return -1;
+               }
+
        BN_CTX_start(ctx);
        if ((r == a) || (r == p))
                rr = BN_CTX_get(ctx);
@@ -204,7 +212,7 @@ int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
        if (BN_is_odd(m))
                {
 #  ifdef MONT_EXP_WORD
-               if (a->top == 1 && !a->neg)
+               if (a->top == 1 && !a->neg && (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) == 0))
                        {
                        BN_ULONG A = a->d[0];
                        ret=BN_mod_exp_mont_word(r,A,p,m,ctx,NULL);
@@ -234,6 +242,13 @@ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
        BIGNUM val[TABLE_SIZE];
        BN_RECP_CTX recp;
 
+       if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
+               {
+               /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */
+               BNerr(BN_F_BN_MOD_EXP_RECP,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+               return -1;
+               }
+
        bits=BN_num_bits(p);
 
        if (bits == 0)
@@ -361,6 +376,11 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
        BIGNUM val[TABLE_SIZE];
        BN_MONT_CTX *mont=NULL;
 
+       if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
+               {
+               return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont);
+               }
+
        bn_check_top(a);
        bn_check_top(p);
        bn_check_top(m);
@@ -493,6 +513,212 @@ err:
        return(ret);
        }
 
+
+/* BN_mod_exp_mont_consttime() stores the precomputed powers in a specific layout
+ * so that accessing any of these table values shows the same access pattern as far
+ * as cache lines are concerned.  The following functions are used to transfer a BIGNUM
+ * from/to that table. */
+
+static int MOD_EXP_CTIME_COPY_TO_PREBUF(BIGNUM *b, int top, unsigned char *buf, int idx, int width)
+       {
+       size_t i, j;
+
+       if (bn_wexpand(b, top) == NULL)
+               return 0;
+       while (b->top < top)
+               {
+               b->d[b->top++] = 0;
+               }
+       
+       for (i = 0, j=idx; i < top * sizeof b->d[0]; i++, j+=width)
+               {
+               buf[j] = ((unsigned char*)b->d)[i];
+               }
+
+       bn_fix_top(b);
+       return 1;
+       }
+
+static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, unsigned char *buf, int idx, int width)
+       {
+       size_t i, j;
+
+       if (bn_wexpand(b, top) == NULL)
+               return 0;
+
+       for (i=0, j=idx; i < top * sizeof b->d[0]; i++, j+=width)
+               {
+               ((unsigned char*)b->d)[i] = buf[j];
+               }
+
+       b->top = top;
+       bn_fix_top(b);
+       return 1;
+       }       
+
+/* Given a pointer value, compute the next address that is a cache line multiple. */
+#define MOD_EXP_CTIME_ALIGN(x_) \
+       ((unsigned char*)(x_) + (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - (((BN_ULONG)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK))))
+
+/* This variant of BN_mod_exp_mont() uses fixed windows and the special
+ * precomputation memory layout to limit data-dependency to a minimum
+ * to protect secret exponents (cf. the hyper-threading timing attacks
+ * pointed out by Colin Percival,
+ * http://www.daemonology.net/hyperthreading-considered-harmful/)
+ */
+int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+                   const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
+       {
+       int i,bits,ret=0,idx,window,wvalue;
+       int top;
+       BIGNUM *r;
+       const BIGNUM *aa;
+       BN_MONT_CTX *mont=NULL;
+
+       int numPowers;
+       unsigned char *powerbufFree=NULL;
+       int powerbufLen = 0;
+       unsigned char *powerbuf=NULL;
+       BIGNUM *computeTemp=NULL, *am=NULL;
+
+       bn_check_top(a);
+       bn_check_top(p);
+       bn_check_top(m);
+
+       top = m->top;
+
+       if (!(m->d[0] & 1))
+               {
+               BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME,BN_R_CALLED_WITH_EVEN_MODULUS);
+               return(0);
+               }
+       bits=BN_num_bits(p);
+       if (bits == 0)
+               {
+               ret = BN_one(rr);
+               return ret;
+               }
+
+       /* Initialize BIGNUM context and allocate intermediate result */
+       BN_CTX_start(ctx);
+       r = BN_CTX_get(ctx);
+       if (r == NULL) goto err;
+
+       /* Allocate a montgomery context if it was not supplied by the caller.
+        * If this is not done, things will break in the montgomery part.
+        */
+       if (in_mont != NULL)
+               mont=in_mont;
+       else
+               {
+               if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
+               if (!BN_MONT_CTX_set(mont,m,ctx)) goto err;
+               }
+
+       /* Get the window size to use with size of p. */
+       window = BN_window_bits_for_ctime_exponent_size(bits);
+
+       /* Allocate a buffer large enough to hold all of the pre-computed
+        * powers of a.
+        */
+       numPowers = 1 << window;
+       powerbufLen = sizeof(m->d[0])*top*numPowers;
+       if ((powerbufFree=(unsigned char*)OPENSSL_malloc(powerbufLen+MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL)
+               goto err;
+               
+       powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree);
+       memset(powerbuf, 0, powerbufLen);
+
+       /* Initialize the intermediate result. Do this early to save double conversion,
+        * once each for a^0 and intermediate result.
+        */
+       if (!BN_to_montgomery(r,BN_value_one(),mont,ctx)) goto err;
+       if (!MOD_EXP_CTIME_COPY_TO_PREBUF(r, top, powerbuf, 0, numPowers)) goto err;
+
+       /* Initialize computeTemp as a^1 with montgomery precalcs */
+       computeTemp = BN_CTX_get(ctx);
+       am = BN_CTX_get(ctx);
+       if (computeTemp==NULL || am==NULL) goto err;
+
+       if (a->neg || BN_ucmp(a,m) >= 0)
+               {
+               if (!BN_mod(am,a,m,ctx))
+                       goto err;
+               aa= am;
+               }
+       else
+               aa=a;
+       if (!BN_to_montgomery(am,aa,mont,ctx)) goto err;
+       if (!BN_copy(computeTemp, am)) goto err;
+       if (!MOD_EXP_CTIME_COPY_TO_PREBUF(am, top, powerbuf, 1, numPowers)) goto err;
+
+       /* If the window size is greater than 1, then calculate
+        * val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1)
+        * (even powers could instead be computed as (a^(i/2))^2
+        * to use the slight performance advantage of sqr over mul).
+        */
+       if (window > 1)
+               {
+               for (i=2; i<numPowers; i++)
+                       {
+                       /* Calculate a^i = a^(i-1) * a */
+                       if (!BN_mod_mul_montgomery(computeTemp,am,computeTemp,mont,ctx))
+                               goto err;
+                       if (!MOD_EXP_CTIME_COPY_TO_PREBUF(computeTemp, top, powerbuf, i, numPowers)) goto err;
+                       }
+               }
+
+       /* Adjust the number of bits up to a multiple of the window size.
+        * If the exponent length is not a multiple of the window size, then
+        * this pads the most significant bits with zeros to normalize the
+        * scanning loop to there's no special cases.
+        *
+        * * NOTE: Making the window size a power of two less than the native
+        * * word size ensures that the padded bits won't go past the last
+        * * word in the internal BIGNUM structure. Going past the end will
+        * * still produce the correct result, but causes a different branch
+        * * to be taken in the BN_is_bit_set function.
+        */
+       bits = ((bits+window-1)/window)*window;
+       idx=bits-1;     /* The top bit of the window */
+
+       /* Scan the exponent one window at a time starting from the most
+        * significant bits.
+        */
+       while (idx >= 0)
+               {
+               wvalue=0; /* The 'value' of the window */
+               
+               /* Scan the window, squaring the result as we go */
+               for (i=0; i<window; i++,idx--)
+                       {
+                       if (!BN_mod_mul_montgomery(r,r,r,mont,ctx))     goto err;
+                       wvalue = (wvalue<<1)+BN_is_bit_set(p,idx);
+                       }
+               
+               /* Fetch the appropriate pre-computed value from the pre-buf */
+               if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(computeTemp, top, powerbuf, wvalue, numPowers)) goto err;
+
+               /* Multiply the result into the intermediate result */
+               if (!BN_mod_mul_montgomery(r,r,computeTemp,mont,ctx)) goto err;
+               }
+
+       /* Convert the final result from montgomery to standard format */
+       if (!BN_from_montgomery(rr,r,mont,ctx)) goto err;
+       ret=1;
+err:
+       if ((in_mont == NULL) && (mont != NULL)) BN_MONT_CTX_free(mont);
+       if (powerbuf!=NULL)
+               {
+               OPENSSL_cleanse(powerbuf,powerbufLen);
+               OPENSSL_free(powerbufFree);
+               }
+       if (am!=NULL) BN_clear(am);
+       if (computeTemp!=NULL) BN_clear(computeTemp);
+       BN_CTX_end(ctx);
+       return(ret);
+       }
+
 int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
                          const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont)
        {
@@ -517,6 +743,13 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
 #define BN_TO_MONTGOMERY_WORD(r, w, mont) \
                (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx))
 
+       if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
+               {
+               /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */
+               BNerr(BN_F_BN_MOD_EXP_MONT_WORD,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+               return -1;
+               }
+
        bn_check_top(p);
        bn_check_top(m);
 
@@ -644,6 +877,13 @@ int BN_mod_exp_simple(BIGNUM *r,
        BIGNUM *d;
        BIGNUM val[TABLE_SIZE];
 
+       if (BN_get_flags(p, BN_FLG_EXP_CONSTTIME) != 0)
+               {
+               /* BN_FLG_EXP_CONSTTIME only supported by BN_mod_exp_mont() */
+               BNerr(BN_F_BN_MOD_EXP_SIMPLE,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+               return -1;
+               }
+
        bits=BN_num_bits(p);
 
        if (bits == 0)
index 253e195e238537a306dc43697ebf460d820d71d0..a84998f2bd423d628fc82f37f6522f1f6c1d6c02 100644 (file)
@@ -177,6 +177,45 @@ struct bignum_ctx
 
 
 
+/* BN_mod_exp_mont_conttime is based on the assumption that the
+ * L1 data cache line width of the target processor is at least
+ * the following value.
+ */
+#define MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH     ( 64 )
+#define MOD_EXP_CTIME_MIN_CACHE_LINE_MASK      (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - 1)
+
+/* Window sizes optimized for fixed window size modular exponentiation
+ * algorithm (BN_mod_exp_mont_consttime).
+ *
+ * To achieve the security goals of BN_mode_exp_mont_consttime, the
+ * maximum size of the window must not exceed
+ * log_2(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH). 
+ *
+ * Window size thresholds are defined for cache line sizes of 32 and 64,
+ * cache line sizes where log_2(32)=5 and log_2(64)=6 respectively. A
+ * window size of 7 should only be used on processors that have a 128
+ * byte or greater cache line size.
+ */
+#if MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 64
+
+#  define BN_window_bits_for_ctime_exponent_size(b) \
+               ((b) > 937 ? 6 : \
+                (b) > 306 ? 5 : \
+                (b) >  89 ? 4 : \
+                (b) >  22 ? 3 : 1)
+#  define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE   (6)
+
+#elif MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 32
+
+#  define BN_window_bits_for_ctime_exponent_size(b) \
+               ((b) > 306 ? 5 : \
+                (b) >  89 ? 4 : \
+                (b) >  22 ? 3 : 1)
+#  define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE   (5)
+
+#endif
+
+
 /* Pentium pro 16,16,16,32,64 */
 /* Alpha       16,16,16,16.64 */
 #define BN_MULL_SIZE_NORMAL                    (16) /* 32 */
index 28cd3339da6fd2d1f5fe0dcc62b43b789dff0592..685007d330c957c4fdaee8a611f38fadb6c5ee61 100644 (file)
@@ -86,6 +86,7 @@ int test_mont(BIO *bp,BN_CTX *ctx);
 int test_mod(BIO *bp,BN_CTX *ctx);
 int test_mod_mul(BIO *bp,BN_CTX *ctx);
 int test_mod_exp(BIO *bp,BN_CTX *ctx);
+int test_mod_exp_mont_consttime(BIO *bp,BN_CTX *ctx);
 int test_exp(BIO *bp,BN_CTX *ctx);
 int test_kron(BIO *bp,BN_CTX *ctx);
 int test_sqrt(BIO *bp,BN_CTX *ctx);
@@ -213,6 +214,10 @@ int main(int argc, char *argv[])
        if (!test_mod_exp(out,ctx)) goto err;
        BIO_flush(out);
 
+       message(out,"BN_mod_exp_mont_consttime");
+       if (!test_mod_exp_mont_consttime(out,ctx)) goto err;
+       BIO_flush(out);
+
        message(out,"BN_exp");
        if (!test_exp(out,ctx)) goto err;
        BIO_flush(out);
@@ -813,6 +818,57 @@ int test_mod_exp(BIO *bp, BN_CTX *ctx)
        return(1);
        }
 
+int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx)
+       {
+       BIGNUM *a,*b,*c,*d,*e;
+       int i;
+
+       a=BN_new();
+       b=BN_new();
+       c=BN_new();
+       d=BN_new();
+       e=BN_new();
+
+       BN_bntest_rand(c,30,0,1); /* must be odd for montgomery */
+       for (i=0; i<num2; i++)
+               {
+               BN_bntest_rand(a,20+i*5,0,0); /**/
+               BN_bntest_rand(b,2+i,0,0); /**/
+
+               if (!BN_mod_exp_mont_consttime(d,a,b,c,ctx,NULL))
+                       return(00);
+
+               if (bp != NULL)
+                       {
+                       if (!results)
+                               {
+                               BN_print(bp,a);
+                               BIO_puts(bp," ^ ");
+                               BN_print(bp,b);
+                               BIO_puts(bp," % ");
+                               BN_print(bp,c);
+                               BIO_puts(bp," - ");
+                               }
+                       BN_print(bp,d);
+                       BIO_puts(bp,"\n");
+                       }
+               BN_exp(e,a,b,ctx);
+               BN_sub(e,e,d);
+               BN_div(a,b,e,c,ctx);
+               if(!BN_is_zero(b))
+                   {
+                   fprintf(stderr,"Modulo exponentiation test failed!\n");
+                   return 0;
+                   }
+               }
+       BN_free(a);
+       BN_free(b);
+       BN_free(c);
+       BN_free(d);
+       BN_free(e);
+       return(1);
+       }
+
 int test_exp(BIO *bp, BN_CTX *ctx)
        {
        BIGNUM *a,*b,*d,*e,*one;
index 07a1bcf51cfcfccd896304272370d15b5d4da4e3..4d5f221f33ad0f63e017979930cca06e39181ca6 100644 (file)
@@ -321,7 +321,7 @@ void do_mul_exp(BIGNUM *r, BIGNUM *a, BIGNUM *b, BIGNUM *c, BN_CTX *ctx)
 #else /* TEST_SQRT */
                        "2*sqrt [prime == %d (mod 64)] %4d %4d mod %4d"
 #endif
-                       " -> %8.3fms %5.1f (%ld)\n",
+                       " -> %8.6fms %5.1f (%ld)\n",
 #ifdef TEST_SQRT
                        P_MOD_64,
 #endif
index b09cf887055037357a79657033941500e2dc1699..28aaac2ac11505521e7b4e079ae5a085b77c4ba0 100644 (file)
@@ -77,7 +77,7 @@ int main(int argc, char *argv[])
        BIO *out=NULL;
        int i,ret;
        unsigned char c;
-       BIGNUM *r_mont,*r_recp,*r_simple,*a,*b,*m;
+       BIGNUM *r_mont,*r_mont_const,*r_recp,*r_simple,*a,*b,*m;
 
        RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_rand may fail, and we don't
                                               * even check its return value
@@ -88,6 +88,7 @@ int main(int argc, char *argv[])
        ctx=BN_CTX_new();
        if (ctx == NULL) EXIT(1);
        r_mont=BN_new();
+       r_mont_const=BN_new();
        r_recp=BN_new();
        r_simple=BN_new();
        a=BN_new();
@@ -143,8 +144,17 @@ int main(int argc, char *argv[])
                        EXIT(1);
                        }
 
+               ret=BN_mod_exp_mont_consttime(r_mont_const,a,b,m,ctx,NULL);
+               if (ret <= 0)
+                       {
+                       printf("BN_mod_exp_mont_consttime() problems\n");
+                       ERR_print_errors(out);
+                       EXIT(1);
+                       }
+
                if (BN_cmp(r_simple, r_mont) == 0
-                   && BN_cmp(r_simple,r_recp) == 0)
+                   && BN_cmp(r_simple,r_recp) == 0
+                       && BN_cmp(r_simple,r_mont_const) == 0)
                        {
                        printf(".");
                        fflush(stdout);
@@ -153,6 +163,8 @@ int main(int argc, char *argv[])
                        {
                        if (BN_cmp(r_simple,r_mont) != 0)
                                printf("\nsimple and mont results differ\n");
+                       if (BN_cmp(r_simple,r_mont) != 0)
+                               printf("\nsimple and mont const time results differ\n");
                        if (BN_cmp(r_simple,r_recp) != 0)
                                printf("\nsimple and recp results differ\n");
 
@@ -162,11 +174,13 @@ int main(int argc, char *argv[])
                        printf("\nsimple   ="); BN_print(out,r_simple);
                        printf("\nrecp     ="); BN_print(out,r_recp);
                        printf("\nmont     ="); BN_print(out,r_mont);
+                       printf("\nmont_ct  ="); BN_print(out,r_mont_const);
                        printf("\n");
                        EXIT(1);
                        }
                }
        BN_free(r_mont);
+       BN_free(r_mont_const);
        BN_free(r_recp);
        BN_free(r_simple);
        BN_free(a);
index 05851f84294c3bc53b68793ed69f0c18aacfa80c..92c7481e10ad2f27a5d44ccb7a82050b07e2c1f7 100644 (file)
 #include <openssl/crypto.h>
 #include <openssl/ossl_typ.h>
        
-#define DH_FLAG_CACHE_MONT_P   0x01
+#define DH_FLAG_CACHE_MONT_P     0x01
+#define DH_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DH
+                                       * implementation now uses constant time
+                                       * modular exponentiation for secret exponents
+                                       * by default. This flag causes the
+                                       * faster variable sliding window method to
+                                       * be used for all exponents.
+                                       */
 
 #ifdef  __cplusplus
 extern "C" {
index d54a3b11177ee21df48580900db62c73218c0325..f7ed790f35f51a18be1b44951234808e6d1939bb 100644 (file)
@@ -143,8 +143,21 @@ static int generate_key(DH *dh)
                l = dh->length ? dh->length : BN_num_bits(dh->p)-1; /* secret exponent length */
                if (!BN_rand(priv_key, l, 0, 0)) goto err;
                }
-       if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, priv_key,dh->p,ctx,mont))
-               goto err;
+
+       {
+               BIGNUM local_prk;
+               BIGNUM *prk;
+
+               if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0)
+                       {
+                       prk = &local_prk;
+                       BN_with_flags(prk, priv_key, BN_FLG_EXP_CONSTTIME);
+                       }
+               else
+                       prk = priv_key;
+
+               if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) goto err;
+       }
                
        dh->pub_key=pub_key;
        dh->priv_key=priv_key;
@@ -182,6 +195,11 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
                mont = BN_MONT_CTX_set_locked(
                                (BN_MONT_CTX **)&dh->method_mont_p,
                                CRYPTO_LOCK_DH, dh->p, ctx);
+               if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0)
+                       {
+                       /* XXX */
+                       BN_set_flags(dh->priv_key, BN_FLG_EXP_CONSTTIME);
+                       }
                if (!mont)
                        goto err;
                }
@@ -204,7 +222,10 @@ static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
                        const BIGNUM *m, BN_CTX *ctx,
                        BN_MONT_CTX *m_ctx)
        {
-       if (a->top == 1)
+       /* If a is only one word long and constant time is false, use the faster
+        * exponenentiation function.
+        */
+       if (a->top == 1 && ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) != 0))
                {
                BN_ULONG A = a->d[0];
                return BN_mod_exp_mont_word(r,A,p,m,ctx,m_ctx);
index d75077f9fa0819bb07efab05f65f7c7ceef91dbb..b76dede7719842593255ab505b45587677f3beb5 100644 (file)
@@ -136,6 +136,10 @@ int main(int argc, char *argv[])
        b->g=BN_dup(a->g);
        if ((b->p == NULL) || (b->g == NULL)) goto err;
 
+       /* Set a to run with normal modexp and b to use constant time */
+       a->flags &= ~DH_FLAG_NO_EXP_CONSTTIME;
+       b->flags |= DH_FLAG_NO_EXP_CONSTTIME;
+
        if (!DH_generate_key(a)) goto err;
        BIO_puts(out,"pri 1=");
        BN_print(out,a->priv_key);
index 225ff391f9be59f87a325fe6f1f8eae8aa34ddbc..925f11cd579ad2b742617550faa6c3856d4cf6a5 100644 (file)
 #endif
 
 #define DSA_FLAG_CACHE_MONT_P  0x01
+#define DSA_FLAG_NO_EXP_CONSTTIME       0x02 /* new with 0.9.7h; the built-in DSA
+                                              * implementation now uses constant time
+                                              * modular exponentiation for secret exponents
+                                              * by default. This flag causes the
+                                              * faster variable sliding window method to
+                                              * be used for all exponents.
+                                              */
 
 #if defined(OPENSSL_FIPS)
 #define FIPS_DSA_SIZE_T        int
index 30607ca579fed3559f9a89416ec0b2826a35d947..63bd8bff2d8acf42e17332df41ade99c8cb7d497 100644 (file)
@@ -90,8 +90,21 @@ int DSA_generate_key(DSA *dsa)
                }
        else
                pub_key=dsa->pub_key;
+       
+       {
+               BIGNUM local_prk;
+               BIGNUM *prk;
+
+               if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
+                       {
+                       prk = &local_prk;
+                       BN_with_flags(prk, priv_key, BN_FLG_EXP_CONSTTIME);
+                       }
+               else
+                       prk = priv_key;
 
-       if (!BN_mod_exp(pub_key,dsa->g,priv_key,dsa->p,ctx)) goto err;
+               if (!BN_mod_exp(pub_key,dsa->g,prk,dsa->p,ctx)) goto err;
+       }
 
        dsa->priv_key=priv_key;
        dsa->pub_key=pub_key;
index a25a29450028dd2525725b8dcc330adad83cbaaa..e668b079e3a9e24f28d7f5a3f09d70c5c3c33a5c 100644 (file)
@@ -197,6 +197,10 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
        do
                if (!BN_rand_range(&k, dsa->q)) goto err;
        while (BN_is_zero(&k));
+       if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
+               {
+               BN_set_flags(&k, BN_FLG_EXP_CONSTTIME);
+               }
 
        if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
                {
index 4734ce4af85150d93b4c15903fdaf6f92de595eb..55a3756affba55a65298c1cb0ac3b2c98f12521c 100644 (file)
@@ -194,10 +194,19 @@ int main(int argc, char **argv)
                BIO_printf(bio_err,"g value is wrong\n");
                goto end;
                }
+
+       dsa->flags |= DSA_FLAG_NO_EXP_CONSTTIME;
        DSA_generate_key(dsa);
        DSA_sign(0, str1, 20, sig, &siglen, dsa);
        if (DSA_verify(0, str1, 20, sig, siglen, dsa) == 1)
                ret=1;
+
+       dsa->flags &= ~DSA_FLAG_NO_EXP_CONSTTIME;
+       DSA_generate_key(dsa);
+       DSA_sign(0, str1, 20, sig, &siglen, dsa);
+       if (DSA_verify(0, str1, 20, sig, siglen, dsa) == 1)
+               ret=1;
+
 end:
        if (!ret)
                ERR_print_errors(bio_err);
index fc3bb5f86de25c2864395b2865083ed65611dd2f..d18c17ff8b3a5947ce8cc65b2a1be3c34448d78d 100644 (file)
@@ -157,28 +157,35 @@ struct rsa_st
 #define RSA_3  0x3L
 #define RSA_F4 0x10001L
 
-#define RSA_METHOD_FLAG_NO_CHECK       0x01 /* don't check pub/private match */
+#define RSA_METHOD_FLAG_NO_CHECK       0x0001 /* don't check pub/private match */
 
-#define RSA_FLAG_CACHE_PUBLIC          0x02
-#define RSA_FLAG_CACHE_PRIVATE         0x04
-#define RSA_FLAG_BLINDING              0x08
-#define RSA_FLAG_THREAD_SAFE           0x10
+#define RSA_FLAG_CACHE_PUBLIC          0x0002
+#define RSA_FLAG_CACHE_PRIVATE         0x0004
+#define RSA_FLAG_BLINDING              0x0008
+#define RSA_FLAG_THREAD_SAFE           0x0010
 /* This flag means the private key operations will be handled by rsa_mod_exp
  * and that they do not depend on the private key components being present:
  * for example a key stored in external hardware. Without this flag bn_mod_exp
  * gets called when private key components are absent.
  */
-#define RSA_FLAG_EXT_PKEY              0x20
+#define RSA_FLAG_EXT_PKEY              0x0020
 
 /* This flag in the RSA_METHOD enables the new rsa_sign, rsa_verify functions.
  */
-#define RSA_FLAG_SIGN_VER              0x40
-
-#define RSA_FLAG_NO_BLINDING           0x80 /* new with 0.9.6j and 0.9.7b; the built-in
-                                              * RSA implementation now uses blinding by
-                                              * default (ignoring RSA_FLAG_BLINDING),
-                                              * but other engines might not need it
-                                              */
+#define RSA_FLAG_SIGN_VER              0x0040
+
+#define RSA_FLAG_NO_BLINDING           0x0080 /* new with 0.9.6j and 0.9.7b; the built-in
+                                                * RSA implementation now uses blinding by
+                                                * default (ignoring RSA_FLAG_BLINDING),
+                                                * but other engines might not need it
+                                                */
+#define RSA_FLAG_NO_EXP_CONSTTIME      0x0100 /* new with 0.9.7h; the built-in RSA
+                                                * implementation now uses constant time
+                                                * modular exponentiation for secret exponents
+                                                * by default. This flag causes the
+                                                * faster variable sliding window method to
+                                                * be used for all exponents.
+                                                */
 
 #define RSA_PKCS1_PADDING      1
 #define RSA_SSLV23_PADDING     2
index 368ac84f17d268b03d5b3cadf88f7e0b62abc8f9..4aefd5419216d7c91a57598cc7dafc2778bd30c2 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 "cryptlib.h"
@@ -314,10 +367,22 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
                (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)
@@ -427,10 +492,22 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
                (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;
                }
 
@@ -561,6 +638,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;
 
@@ -580,11 +659,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;
@@ -619,10 +712,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:
index 924e9ad1f6c0cf60d79228c644aad75de1e9be8b..218bb2a39bb9c3d4a6420091e2fa3b10a79df43f 100644 (file)
@@ -227,10 +227,10 @@ int main(int argc, char *argv[])
 
     plen = sizeof(ptext_ex) - 1;
 
-    for (v = 0; v < 3; v++)
+    for (v = 0; v < 6; v++)
        {
        key = RSA_new();
-       switch (v) {
+       switch (v%3) {
     case 0:
        clen = key1(key, ctext_ex);
        break;
@@ -241,6 +241,7 @@ int main(int argc, char *argv[])
        clen = key3(key, ctext_ex);
        break;
        }
+       if (v/3 > 1) key->flags |= RSA_FLAG_NO_EXP_CONSTTIME;
 
        num = RSA_public_encrypt(plen, ptext_ex, ctext, key,
                                 RSA_PKCS1_PADDING);
index 96060bd8b39afbf4cb3ad1f72caee66f83f265aa..fb25c0c5c98b8860e0c18aa0c06a6232c2a37575 100755 (executable)
@@ -2875,3 +2875,4 @@ EVP_sha224                              3314      EXIST::FUNCTION:SHA
 EVP_sha256                              3315   EXIST::FUNCTION:SHA
 FIPS_selftest_hmac                      3316   EXIST:OPENSSL_FIPS:FUNCTION:
 FIPS_corrupt_rng                        3317   EXIST:OPENSSL_FIPS:FUNCTION:
+BN_mod_exp_mont_consttime               3318   EXIST::FUNCTION: