libgcrypt: add CVE-2017-7526 fix from Ubuntu
[unleashed-userland.git] / components / library / libgcrypt / patches / 04-CVE-2017-7526-3.patch
blobaf6f9f35731af0cd2432d78167d349c507f86e84
1 From a9f612def801c8145d551d995475e5d51a4c988c Mon Sep 17 00:00:00 2001
2 From: NIIBE Yutaka <gniibe@fsij.org>
3 Date: Thu, 29 Jun 2017 11:48:44 +0900
4 Subject: [PATCH] rsa: Add exponent blinding.
6 * cipher/rsa.c (secret): Blind secret D with randomized nonce R for
7 mpi_powm computation.
9 --
11 Co-authored-by: Werner Koch <wk@gnupg.org>
12 Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
14 The paper describing attack: https://eprint.iacr.org/2017/627
16 Sliding right into disaster: Left-to-right sliding windows leak
17 by Daniel J. Bernstein and Joachim Breitner and Daniel Genkin and
18 Leon Groot Bruinderink and Nadia Heninger and Tanja Lange and
19 Christine van Vredendaal and Yuval Yarom
21 It is well known that constant-time implementations of modular
22 exponentiation cannot use sliding windows. However, software
23 libraries such as Libgcrypt, used by GnuPG, continue to use sliding
24 windows. It is widely believed that, even if the complete pattern of
25 squarings and multiplications is observed through a side-channel
26 attack, the number of exponent bits leaked is not sufficient to
27 carry out a full key-recovery attack against RSA. Specifically,
28 4-bit sliding windows leak only 40% of the bits, and 5-bit sliding
29 windows leak only 33% of the bits.
31 In this paper we demonstrate a complete break of RSA-1024 as
32 implemented in Libgcrypt. Our attack makes essential use of the fact
33 that Libgcrypt uses the left-to-right method for computing the
34 sliding-window expansion. We show for the first time that the
35 direction of the encoding matters: the pattern of squarings and
36 multiplications in left-to-right sliding windows leaks significantly
37 more information about exponent bits than for right-to-left. We show
38 how to incorporate this additional information into the
39 Heninger-Shacham algorithm for partial key reconstruction, and use
40 it to obtain very efficient full key recovery for RSA-1024. We also
41 provide strong evidence that the same attack works for RSA-2048 with
42 only moderately more computation.
44 Exponent blinding is a kind of workaround to add noise. Signal (leak)
45 is still there for non-constant-time implementation.
47 (backported from master commit:
48 8725c99ffa41778f382ca97233183bcd687bb0ce)
49 ---
50 cipher/rsa.c | 32 +++++++++++++++++++++++++-------
51 1 file changed, 25 insertions(+), 7 deletions(-)
53 Index: libgcrypt11-1.5.3/cipher/rsa.c
54 ===================================================================
55 --- libgcrypt11-1.5.3.orig/cipher/rsa.c 2017-07-03 08:20:00.697478903 -0400
56 +++ libgcrypt11-1.5.3/cipher/rsa.c 2017-07-03 08:20:00.673478904 -0400
57 @@ -711,15 +711,33 @@ secret(gcry_mpi_t output, gcry_mpi_t inp
58 gcry_mpi_t m1 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
59 gcry_mpi_t m2 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
60 gcry_mpi_t h = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
61 + gcry_mpi_t D_blind = mpi_alloc_secure ( mpi_get_nlimbs(skey->n) + 1 );
62 + gcry_mpi_t r;
63 + unsigned int r_nbits;
65 - /* m1 = c ^ (d mod (p-1)) mod p */
66 + r_nbits = mpi_get_nbits (skey->p) / 4;
67 + if (r_nbits < 96)
68 + r_nbits = 96;
69 + r = mpi_alloc_secure ((r_nbits + BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB);
71 + /* d_blind = (d mod (p-1)) + (p-1) * r */
72 + /* m1 = c ^ d_blind mod p */
73 + _gcry_mpi_randomize (r, r_nbits, GCRY_WEAK_RANDOM);
74 + mpi_set_highbit (r, r_nbits - 1);
75 mpi_sub_ui( h, skey->p, 1 );
76 - mpi_fdiv_r( h, skey->d, h );
77 - mpi_powm( m1, input, h, skey->p );
78 - /* m2 = c ^ (d mod (q-1)) mod q */
79 + mpi_mul ( D_blind, h, r );
80 + mpi_fdiv_r ( h, skey->d, h );
81 + mpi_add ( D_blind, D_blind, h );
82 + mpi_powm( m1, input, D_blind, skey->p );
83 + /* d_blind = (d mod (q-1)) + (q-1) * r */
84 + /* m2 = c ^ d_blind mod q */
85 + _gcry_mpi_randomize (r, r_nbits, GCRY_WEAK_RANDOM);
86 + mpi_set_highbit (r, r_nbits - 1);
87 mpi_sub_ui( h, skey->q, 1 );
88 - mpi_fdiv_r( h, skey->d, h );
89 - mpi_powm( m2, input, h, skey->q );
90 + mpi_mul ( D_blind, h, r );
91 + mpi_fdiv_r ( h, skey->d, h );
92 + mpi_add ( D_blind, D_blind, h );
93 + mpi_powm( m2, input, D_blind, skey->q );
94 /* h = u * ( m2 - m1 ) mod q */
95 mpi_sub( h, m2, m1 );
96 if ( mpi_is_neg( h ) )