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;