From 8725c99ffa41778f382ca97233183bcd687bb0ce Mon Sep 17 00:00:00 2001
From: NIIBE Yutaka
Date: Thu, 29 Jun 2017 11:11:37 +0900
Subject: [PATCH] rsa: Add exponent blinding.
* cipher/rsa.c (secret_core_crt): Blind secret D with randomized
nonce R for mpi_powm computation.

Coauthoredby: Werner Koch
Signedoffby: NIIBE Yutaka
The paper describing attack: https://eprint.iacr.org/2017/627
Sliding right into disaster: Lefttoright sliding windows leak
by Daniel J. Bernstein and Joachim Breitner and Daniel Genkin and
Leon Groot Bruinderink and Nadia Heninger and Tanja Lange and
Christine van Vredendaal and Yuval Yarom
It is well known that constanttime implementations of modular
exponentiation cannot use sliding windows. However, software
libraries such as Libgcrypt, used by GnuPG, continue to use sliding
windows. It is widely believed that, even if the complete pattern of
squarings and multiplications is observed through a sidechannel
attack, the number of exponent bits leaked is not sufficient to
carry out a full keyrecovery attack against RSA. Specifically,
4bit sliding windows leak only 40% of the bits, and 5bit sliding
windows leak only 33% of the bits.
In this paper we demonstrate a complete break of RSA1024 as
implemented in Libgcrypt. Our attack makes essential use of the fact
that Libgcrypt uses the lefttoright method for computing the
slidingwindow expansion. We show for the first time that the
direction of the encoding matters: the pattern of squarings and
multiplications in lefttoright sliding windows leaks significantly
more information about exponent bits than for righttoleft. We show
how to incorporate this additional information into the
HeningerShacham algorithm for partial key reconstruction, and use
it to obtain very efficient full key recovery for RSA1024. We also
provide strong evidence that the same attack works for RSA2048 with
only moderately more computation.
Exponent blinding is a kind of workaround to add noise. Signal (leak)
is still there for nonconstanttime implementation.

cipher/rsa.c  31 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+), 5 deletions()
diff git a/cipher/rsa.c b/cipher/rsa.c
index 9f83e8f2..ce73f106 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 (p1)) 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_LIMB1)/BITS_PER_MPI_LIMB );
+
+ /* d_blind = (d mod (p1)) + (p1) * 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 (q1)) mod q */
+ /* d_blind = (d mod (q1)) + (q1) * 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 );

2.11.0