X-Git-Url: http://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=blobdiff_plain;f=cipher%2Frsa.c;h=9f83e8f239fb1f6467d7657ad4dda671fd395ade;hp=7f12ecd610851dce82e34e608c2d4439f7e4a84f;hb=e6a3dc9900433bbc8ad362a595a3837318c28fa9;hpb=d091610377b2c92cf385282b1adfc30fa6cd5c75

diff --git a/cipher/rsa.c b/cipher/rsa.c
index 7f12ecd..9f83e8f 100644
--- a/cipher/rsa.c
+++ b/cipher/rsa.c
@@ -991,20 +991,64 @@ stronger_key_check ( RSA_secret_key *skey )
 #endif
 
 
-
-/****************
- * Secret key operation. Encrypt INPUT with SKEY and put result into OUTPUT.
+
+/* Secret key operation - standard version.
  *
  *	m = c^d mod n
- *
- * Or faster:
+ */
+static void
+secret_core_std (gcry_mpi_t M, gcry_mpi_t C,
+                 gcry_mpi_t D, gcry_mpi_t N)
+{
+  mpi_powm (M, C, D, N);
+}
+
+
+/* Secret key operation - using the CRT.
  *
  *      m1 = c ^ (d mod (p-1)) mod p
  *      m2 = c ^ (d mod (q-1)) mod q
  *      h = u * (m2 - m1) mod q
  *      m = m1 + h * p
- *
- * Where m is OUTPUT, c is INPUT and d,n,p,q,u are elements of SKEY.
+ */
+static void
+secret_core_crt (gcry_mpi_t M, gcry_mpi_t C,
+                 gcry_mpi_t D, unsigned int Nlimbs,
+                 gcry_mpi_t P, gcry_mpi_t Q, gcry_mpi_t U)
+{
+  gcry_mpi_t m1 = mpi_alloc_secure ( Nlimbs + 1 );
+  gcry_mpi_t m2 = mpi_alloc_secure ( Nlimbs + 1 );
+  gcry_mpi_t h  = mpi_alloc_secure ( Nlimbs + 1 );
+
+  /* m1 = c ^ (d mod (p-1)) mod p */
+  mpi_sub_ui ( h, P, 1 );
+  mpi_fdiv_r ( h, D, h );
+  mpi_powm ( m1, C, h, P );
+
+  /* m2 = c ^ (d mod (q-1)) mod q */
+  mpi_sub_ui ( h, Q, 1  );
+  mpi_fdiv_r ( h, D, h );
+  mpi_powm ( m2, C, h, Q );
+
+  /* h = u * ( m2 - m1 ) mod q */
+  mpi_sub ( h, m2, m1 );
+  if ( mpi_has_sign ( h ) )
+    mpi_add ( h, h, Q );
+  mpi_mulm ( h, U, h, Q );
+
+  /* m = m1 + h * p */
+  mpi_mul ( h, h, P );
+  mpi_add ( M, m1, h );
+
+  mpi_free ( h );
+  mpi_free ( m1 );
+  mpi_free ( m2 );
+}
+
+
+/* Secret key operation.
+ * Encrypt INPUT with SKEY and put result into
+ * OUTPUT.  SKEY has the secret key parameters.
  */
 static void
 secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey )
@@ -1014,37 +1058,16 @@ secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey )
 
   if (!skey->p || !skey->q || !skey->u)
     {
-      mpi_powm (output, input, skey->d, skey->n);
+      secret_core_std (output, input, skey->d, skey->n);
     }
   else
     {
-      gcry_mpi_t m1 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
-      gcry_mpi_t m2 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
-      gcry_mpi_t h  = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
-
-      /* m1 = c ^ (d mod (p-1)) mod p */
-      mpi_sub_ui( h, skey->p, 1  );
-      mpi_fdiv_r( h, skey->d, h );
-      mpi_powm( m1, input, h, skey->p );
-      /* m2 = c ^ (d mod (q-1)) mod q */
-      mpi_sub_ui( h, skey->q, 1  );
-      mpi_fdiv_r( h, skey->d, h );
-      mpi_powm( m2, input, h, skey->q );
-      /* h = u * ( m2 - m1 ) mod q */
-      mpi_sub( h, m2, m1 );
-      if ( mpi_has_sign ( h ) )
-        mpi_add ( h, h, skey->q );
-      mpi_mulm( h, skey->u, h, skey->q );
-      /* m = m1 + h * p */
-      mpi_mul ( h, h, skey->p );
-      mpi_add ( output, m1, h );
-
-      mpi_free ( h );
-      mpi_free ( m1 );
-      mpi_free ( m2 );
+      secret_core_crt (output, input, skey->d, mpi_get_nlimbs (skey->n),
+                       skey->p, skey->q, skey->u);
     }
 }
 
+
 static void
 secret_blinded (gcry_mpi_t output, gcry_mpi_t input,
                 RSA_secret_key *sk, unsigned int nbits)
@@ -1088,6 +1111,7 @@ secret_blinded (gcry_mpi_t output, gcry_mpi_t input,
   _gcry_mpi_release (ri);
 }
 
+
 /*********************************************
  **************  interface  ******************
  *********************************************/



X-Git-Url: http://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=blobdiff_plain;f=cipher%2Frsa.c;h=ce73f106b2699b498e5053a08d625349a7c34099;hp=9f83e8f239fb1f6467d7657ad4dda671fd395ade;hb=8725c99ffa41778f382ca97233183bcd687bb0ce;hpb=78130828e9a140a9de4dafadbc844dbb64cb709a

diff --git a/cipher/rsa.c b/cipher/rsa.c
index 9f83e8f..ce73f10 100644
--- a/cipher/rsa.c
+++ b/cipher/rsa.c
@@ -1019,16 +1019,37 @@ secret_core_crt (gcry_mpi_t M, gcry_mpi_t C,
   gcry_mpi_t m1 = mpi_alloc_secure ( Nlimbs + 1 );
   gcry_mpi_t m2 = mpi_alloc_secure ( Nlimbs + 1 );
   gcry_mpi_t h  = mpi_alloc_secure ( Nlimbs + 1 );
-
-  /* m1 = c ^ (d mod (p-1)) mod p */
+  gcry_mpi_t D_blind = mpi_alloc_secure ( Nlimbs + 1 );
+  gcry_mpi_t r;
+  unsigned int r_nbits;
+
+  r_nbits = mpi_get_nbits (P) / 4;
+  if (r_nbits < 96)
+    r_nbits = 96;
+  r = mpi_alloc_secure ( (r_nbits + BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
+
+  /* d_blind = (d mod (p-1)) + (p-1) * r            */
+  /* m1 = c ^ d_blind mod p */
+  _gcry_mpi_randomize (r, r_nbits, GCRY_WEAK_RANDOM);
+  mpi_set_highbit (r, r_nbits - 1);
   mpi_sub_ui ( h, P, 1 );
+  mpi_mul ( D_blind, h, r );
   mpi_fdiv_r ( h, D, h );
-  mpi_powm ( m1, C, h, P );
+  mpi_add ( D_blind, D_blind, h );
+  mpi_powm ( m1, C, D_blind, P );
 
-  /* m2 = c ^ (d mod (q-1)) mod q */
+  /* d_blind = (d mod (q-1)) + (q-1) * r            */
+  /* m2 = c ^ d_blind mod q */
+  _gcry_mpi_randomize (r, r_nbits, GCRY_WEAK_RANDOM);
+  mpi_set_highbit (r, r_nbits - 1);
   mpi_sub_ui ( h, Q, 1  );
+  mpi_mul ( D_blind, h, r );
   mpi_fdiv_r ( h, D, h );
-  mpi_powm ( m2, C, h, Q );
+  mpi_add ( D_blind, D_blind, h );
+  mpi_powm ( m2, C, D_blind, Q );
+
+  mpi_free ( r );
+  mpi_free ( D_blind );
 
   /* h = u * ( m2 - m1 ) mod q */
   mpi_sub ( h, m2, m1 );



--- a/mpi/mpi-pow.c
+++ b/mpi/mpi-pow.c
@@ -573,6 +573,8 @@ _gcry_mpi_powm (gcry_mpi_t res,
         MPN_COPY (precomp[i], rp, rsize);
       }
 
+    if (msize > max_u_size)
+      max_u_size = msize;
     base_u = mpi_alloc_limb_space (max_u_size, esec);
     MPN_ZERO (base_u, max_u_size);
 
@@ -609,12 +611,8 @@ _gcry_mpi_powm (gcry_mpi_t res,
       if (e == 0)
         {
           j += c;
-          i--;
-          if ( i < 0 )
-            {
-              c = 0;
-              break;
-            }
+          if ( --i < 0 )
+            break;
 
           e = ep[i];
           c = BITS_PER_MPI_LIMB;
@@ -623,79 +621,78 @@ _gcry_mpi_powm (gcry_mpi_t res,
         {
           int c0;
           mpi_limb_t e0;
+          struct gcry_mpi w, u;
+          w.sign = u.sign = 0;
+          w.flags = u.flags = 0;
+          w.d = base_u;
 
           count_leading_zeros (c0, e);
           e = (e << c0);
           c -= c0;
           j += c0;
 
+          e0 = (e >> (BITS_PER_MPI_LIMB - W));
           if (c >= W)
-            {
-              e0 = (e >> (BITS_PER_MPI_LIMB - W));
-              e = (e << W);
-              c -= W;
-            }
+            c0 = 0;
           else
             {
-              i--;
-              if ( i < 0 )
+              if ( --i < 0 )
                 {
-                  e = (e >> (BITS_PER_MPI_LIMB - c));
-                  break;
+                  e0 = (e >> (BITS_PER_MPI_LIMB - c));
+                  j += c - W;
+                  goto last_step;
+                }
+              else
+                {
+                  c0 = c;
+                  e = ep[i];
+                  c = BITS_PER_MPI_LIMB;
+                  e0 |= (e >> (BITS_PER_MPI_LIMB - (W - c0)));
                 }
-
-              c0 = c;
-              e0 = (e >> (BITS_PER_MPI_LIMB - W))
-                | (ep[i] >> (BITS_PER_MPI_LIMB - W + c0));
-              e = (ep[i] << (W - c0));
-              c = BITS_PER_MPI_LIMB - W + c0;
             }
 
+          e = e << (W - c0);
+          c -= (W - c0);
+
+        last_step:
           count_trailing_zeros (c0, e0);
           e0 = (e0 >> c0) >> 1;
 
-          for (j += W - c0; j; j--)
+          for (j += W - c0; j >= 0; j--)
             {
-              mul_mod (xp, &xsize, rp, rsize, rp, rsize, mp, msize, &karactx);
-              tp = rp; rp = xp; xp = tp;
-              rsize = xsize;
-            }
 
-          /*
-           *  base_u <= precomp[e0]
-           *  base_u_size <= precomp_size[e0]
-           */
-          base_u_size = 0;
-          for (k = 0; k < (1<< (W - 1)); k++)
-            {
-              struct gcry_mpi w, u;
-              w.alloced = w.nlimbs = precomp_size[k];
-              u.alloced = u.nlimbs = precomp_size[k];
-              w.sign = u.sign = 0;
-              w.flags = u.flags = 0;
-              w.d = base_u;
-              u.d = precomp[k];
+              /*
+               *  base_u <= precomp[e0]
+               *  base_u_size <= precomp_size[e0]
+               */
+              base_u_size = 0;
+              for (k = 0; k < (1<< (W - 1)); k++)
+                {
+                  w.alloced = w.nlimbs = precomp_size[k];
+                  u.alloced = u.nlimbs = precomp_size[k];
+                  u.d = precomp[k];
 
-              mpi_set_cond (&w, &u, k == e0);
-              base_u_size |= (precomp_size[k] & ((mpi_size_t)0 - (k == e0)) );
-            }
+                  mpi_set_cond (&w, &u, k == e0);
+                  base_u_size |= ( precomp_size[k] & (0UL - (k == e0)) );
+                }
 
-          mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size,
-                   mp, msize, &karactx);
-          tp = rp; rp = xp; xp = tp;
-          rsize = xsize;
+              w.alloced = w.nlimbs = rsize;
+              u.alloced = u.nlimbs = rsize;
+              u.d = rp;
+              mpi_set_cond (&w, &u, j != 0);
+              base_u_size ^= ((base_u_size ^ rsize)  & (0UL - (j != 0)));
+
+              mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size,
+                       mp, msize, &karactx);
+              tp = rp; rp = xp; xp = tp;
+              rsize = xsize;
+            }
 
           j = c0;
+          if ( i < 0 )
+            break;
         }
 
-    if (c != 0)
-      {
-        j += c;
-        count_trailing_zeros (c, e);
-        e = (e >> c);
-        j -= c;
-      }
-
     while (j--)
       {
         mul_mod (xp, &xsize, rp, rsize, rp, rsize, mp, msize, &karactx);
@@ -703,40 +700,6 @@ _gcry_mpi_powm (gcry_mpi_t res,
         rsize = xsize;
       }
 
-    if (e != 0)
-      {
-        /*
-         * base_u <= precomp[(e>>1)]
-         * base_u_size <= precomp_size[(e>>1)]
-         */
-        base_u_size = 0;
-        for (k = 0; k < (1<< (W - 1)); k++)
-          {
-            struct gcry_mpi w, u;
-            w.alloced = w.nlimbs = precomp_size[k];
-            u.alloced = u.nlimbs = precomp_size[k];
-            w.sign = u.sign = 0;
-            w.flags = u.flags = 0;
-            w.d = base_u;
-            u.d = precomp[k];
-
-            mpi_set_cond (&w, &u, k == (e>>1));
-            base_u_size |= (precomp_size[k] & ((mpi_size_t)0 - (k == (e>>1))) );
-          }
-
-        mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size,
-                 mp, msize, &karactx);
-        tp = rp; rp = xp; xp = tp;
-        rsize = xsize;
-
-        for (; c; c--)
-          {
-            mul_mod (xp, &xsize, rp, rsize, rp, rsize, mp, msize, &karactx);
-            tp = rp; rp = xp; xp = tp;
-            rsize = xsize;
-          }
-      }
-
     /* We shifted MOD, the modulo reduction argument, left
        MOD_SHIFT_CNT steps.  Adjust the result by reducing it with the
        original MOD.



From 619ebae9847831f43314a95cc3180f4b329b4d3b Mon Sep 17 00:00:00 2001
From: NIIBE Yutaka <gniibe@fsij.org>
Date: Fri, 7 Jul 2017 11:39:09 +0900
Subject: [PATCH] Fix mpi_pow alternative implementation.

* mpi/mpi-pow.c [USE_ALGORITHM_SIMPLE_EXPONENTIATION] (_gcry_mpi_powm):
Allocate size fix.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
---
 mpi/mpi-pow.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c
index 3cba6903..3d6d68c8 100644
--- a/mpi/mpi-pow.c
+++ b/mpi/mpi-pow.c
@@ -189,8 +189,8 @@ _gcry_mpi_powm (gcry_mpi_t res,
     mpi_limb_t carry_limb;
     struct karatsuba_ctx karactx;
 
-    xp_nlimbs = msec? (2 * (msize + 1)):0;
-    xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec );
+    xp_nlimbs = msec? size:0;
+    xp = xp_marker = mpi_alloc_limb_space( size, msec );
 
     memset( &karactx, 0, sizeof karactx );
     negative_result = (ep[0] & 1) && bsign;



From 66ed4d53789892def7b237756d8a0ab28df9d222 Mon Sep 17 00:00:00 2001
From: NIIBE Yutaka <gniibe@fsij.org>
Date: Fri, 7 Jul 2017 12:00:03 +0900
Subject: [PATCH] mpi: Fix mpi_pow alternative implementation.

* mpi/mpi-pow.c
  [USE_ALGORITHM_SIMPLE_EXPONENTIATION] (_gcry_mpi_powm): Use
  mpi_set_cond.

--

Limbs of RES may be allocated more before the call of mpi_pow,
but it only uses the space of SIZE.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
---
 mpi/mpi-pow.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c
index 3d6d68c8..54f477b2 100644
--- a/mpi/mpi-pow.c
+++ b/mpi/mpi-pow.c
@@ -188,10 +188,16 @@ _gcry_mpi_powm (gcry_mpi_t res,
     mpi_limb_t e;
     mpi_limb_t carry_limb;
     struct karatsuba_ctx karactx;
+    struct gcry_mpi w, u;
 
     xp_nlimbs = msec? size:0;
     xp = xp_marker = mpi_alloc_limb_space( size, msec );
 
+    w.sign = u.sign = 0;
+    w.flags = u.flags = 0;
+    w.alloced = w.nlimbs = size; /* RES->alloc may be longer.  */
+    u.alloced = u.nlimbs = size;
+
     memset( &karactx, 0, sizeof karactx );
     negative_result = (ep[0] & 1) && bsign;
 
@@ -267,11 +273,11 @@ _gcry_mpi_powm (gcry_mpi_t res,
                     xsize = msize;
                   }
               }
-            if ( (mpi_limb_signed_t)e < 0 )
-              {
-                tp = rp; rp = xp; xp = tp;
-                rsize = xsize;
-              }
+
+            w.d = rp;
+            u.d = xp;
+            mpi_set_cond (&w, &u, ((mpi_limb_signed_t)e < 0));
+
             e <<= 1;
             c--;
           }



From 61b0f52c1cc85bf8c3cac9aba40e28682e4e1b8b Mon Sep 17 00:00:00 2001
From: NIIBE Yutaka <gniibe@fsij.org>
Date: Fri, 7 Jul 2017 14:48:17 +0900
Subject: [PATCH] mpi: Minor fix of mpi_pow.

* mpi/mpi-pow.c (_gcry_mpi_powm): Allocate size fix.

--

Same thing of 619ebae9847831f43314a95cc3180f4b329b4d3b applied.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
---
 mpi/mpi-pow.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c
index 54f477b2..62b4a808 100644
--- a/mpi/mpi-pow.c
+++ b/mpi/mpi-pow.c
@@ -552,8 +552,8 @@ _gcry_mpi_powm (gcry_mpi_t res,
     struct karatsuba_ctx karactx;
     mpi_ptr_t tp;
 
-    xp_nlimbs = msec? (2 * (msize + 1)):0;
-    xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec );
+    xp_nlimbs = msec? size:0;
+    xp = xp_marker = mpi_alloc_limb_space( size, msec );
 
     memset( &karactx, 0, sizeof karactx );
     negative_result = (ep[0] & 1) && bsign;