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 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 --- 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 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 --- 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 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 --- 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;