summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorRoss Burton <ross.burton@intel.com>2017-07-18 23:07:35 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2017-07-19 11:30:27 +0100
commit2e132efa2f985f72c3b6c5402747d0b0e1fc540a (patch)
tree0500f6da1fb28c033f65650a3fc46d9424eb016e /meta
parentbbe268e060d9e5a2e37514eaf078de5147c15d58 (diff)
downloadpoky-2e132efa2f985f72c3b6c5402747d0b0e1fc540a.tar.gz
libgcrypt: fix CVE-2017-7526
Fixes CVE-2017-7526, 'flush+reload side-channel attack on RSA secret keys dubbed "Sliding right into disaster"'. (From OE-Core rev: e3911133ee9aad7cc3ae89faea80a097f6614fab) Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
-rw-r--r--meta/recipes-support/libgcrypt/files/CVE-2017-7526.patch455
-rw-r--r--meta/recipes-support/libgcrypt/libgcrypt.inc1
2 files changed, 456 insertions, 0 deletions
diff --git a/meta/recipes-support/libgcrypt/files/CVE-2017-7526.patch b/meta/recipes-support/libgcrypt/files/CVE-2017-7526.patch
new file mode 100644
index 0000000000..7180e7af2c
--- /dev/null
+++ b/meta/recipes-support/libgcrypt/files/CVE-2017-7526.patch
@@ -0,0 +1,455 @@
1Flush+reload side-channel attack on RSA secret keys dubbed "Sliding right
2into disaster".
3
4CVE: CVE-2017-7526
5Upstream-Status: Backport
6Signed-off-by: Ross Burton <ross.burton@intel.com>
7
8From 56bd068335500207dea2cece9cc662bcd9658951 Mon Sep 17 00:00:00 2001
9From: NIIBE Yutaka <gniibe@fsij.org>
10Date: Tue, 4 Apr 2017 17:38:05 +0900
11Subject: [PATCH 1/5] mpi: Simplify mpi_powm.
12
13* mpi/mpi-pow.c (_gcry_mpi_powm): Simplify the loop.
14
15--
16
17This fix is not a solution for the problem reported (yet). The
18problem is that the current algorithm of _gcry_mpi_powm depends on
19exponent and some information leaks is possible.
20
21Reported-by: Andreas Zankl <andreas.zankl@aisec.fraunhofer.de>
22Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
23
24(backport from master commit:
25719468e53133d3bdf12156c5bfdea2bf15f9f6f1)
26
27Signed-off-by: Ross Burton <ross.burton@intel.com>
28---
29 mpi/mpi-pow.c | 105 +++++++++++++++++-----------------------------------------
30 1 file changed, 30 insertions(+), 75 deletions(-)
31
32diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c
33index a780ebd1..7b3dc318 100644
34--- a/mpi/mpi-pow.c
35+++ b/mpi/mpi-pow.c
36@@ -609,12 +609,8 @@ _gcry_mpi_powm (gcry_mpi_t res,
37 if (e == 0)
38 {
39 j += c;
40- i--;
41- if ( i < 0 )
42- {
43- c = 0;
44- break;
45- }
46+ if ( --i < 0 )
47+ break;
48
49 e = ep[i];
50 c = BITS_PER_MPI_LIMB;
51@@ -629,38 +625,33 @@ _gcry_mpi_powm (gcry_mpi_t res,
52 c -= c0;
53 j += c0;
54
55+ e0 = (e >> (BITS_PER_MPI_LIMB - W));
56 if (c >= W)
57- {
58- e0 = (e >> (BITS_PER_MPI_LIMB - W));
59- e = (e << W);
60- c -= W;
61- }
62+ c0 = 0;
63 else
64 {
65- i--;
66- if ( i < 0 )
67+ if ( --i < 0 )
68 {
69- e = (e >> (BITS_PER_MPI_LIMB - c));
70- break;
71+ e0 = (e >> (BITS_PER_MPI_LIMB - c));
72+ j += c - W;
73+ goto last_step;
74+ }
75+ else
76+ {
77+ c0 = c;
78+ e = ep[i];
79+ c = BITS_PER_MPI_LIMB;
80+ e0 |= (e >> (BITS_PER_MPI_LIMB - (W - c0)));
81 }
82-
83- c0 = c;
84- e0 = (e >> (BITS_PER_MPI_LIMB - W))
85- | (ep[i] >> (BITS_PER_MPI_LIMB - W + c0));
86- e = (ep[i] << (W - c0));
87- c = BITS_PER_MPI_LIMB - W + c0;
88 }
89
90+ e = e << (W - c0);
91+ c -= (W - c0);
92+
93+ last_step:
94 count_trailing_zeros (c0, e0);
95 e0 = (e0 >> c0) >> 1;
96
97- for (j += W - c0; j; j--)
98- {
99- mul_mod (xp, &xsize, rp, rsize, rp, rsize, mp, msize, &karactx);
100- tp = rp; rp = xp; xp = tp;
101- rsize = xsize;
102- }
103-
104 /*
105 * base_u <= precomp[e0]
106 * base_u_size <= precomp_size[e0]
107@@ -677,25 +668,23 @@ _gcry_mpi_powm (gcry_mpi_t res,
108 u.d = precomp[k];
109
110 mpi_set_cond (&w, &u, k == e0);
111- base_u_size |= (precomp_size[k] & ((mpi_size_t)0 - (k == e0)) );
112+ base_u_size |= ( precomp_size[k] & ((mpi_size_t)0 - (k == e0)) );
113 }
114
115- mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size,
116- mp, msize, &karactx);
117- tp = rp; rp = xp; xp = tp;
118- rsize = xsize;
119+ for (j += W - c0; j >= 0; j--)
120+ {
121+ mul_mod (xp, &xsize, rp, rsize,
122+ j == 0 ? base_u : rp, j == 0 ? base_u_size : rsize,
123+ mp, msize, &karactx);
124+ tp = rp; rp = xp; xp = tp;
125+ rsize = xsize;
126+ }
127
128 j = c0;
129+ if ( i < 0 )
130+ break;
131 }
132
133- if (c != 0)
134- {
135- j += c;
136- count_trailing_zeros (c, e);
137- e = (e >> c);
138- j -= c;
139- }
140-
141 while (j--)
142 {
143 mul_mod (xp, &xsize, rp, rsize, rp, rsize, mp, msize, &karactx);
144@@ -703,40 +692,6 @@ _gcry_mpi_powm (gcry_mpi_t res,
145 rsize = xsize;
146 }
147
148- if (e != 0)
149- {
150- /*
151- * base_u <= precomp[(e>>1)]
152- * base_u_size <= precomp_size[(e>>1)]
153- */
154- base_u_size = 0;
155- for (k = 0; k < (1<< (W - 1)); k++)
156- {
157- struct gcry_mpi w, u;
158- w.alloced = w.nlimbs = precomp_size[k];
159- u.alloced = u.nlimbs = precomp_size[k];
160- w.sign = u.sign = 0;
161- w.flags = u.flags = 0;
162- w.d = base_u;
163- u.d = precomp[k];
164-
165- mpi_set_cond (&w, &u, k == (e>>1));
166- base_u_size |= (precomp_size[k] & ((mpi_size_t)0 - (k == (e>>1))) );
167- }
168-
169- mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size,
170- mp, msize, &karactx);
171- tp = rp; rp = xp; xp = tp;
172- rsize = xsize;
173-
174- for (; c; c--)
175- {
176- mul_mod (xp, &xsize, rp, rsize, rp, rsize, mp, msize, &karactx);
177- tp = rp; rp = xp; xp = tp;
178- rsize = xsize;
179- }
180- }
181-
182 /* We shifted MOD, the modulo reduction argument, left
183 MOD_SHIFT_CNT steps. Adjust the result by reducing it with the
184 original MOD.
185--
1862.11.0
187
188
189From 6e237c8c48d257dc315e364791d284c6bf3fa703 Mon Sep 17 00:00:00 2001
190From: NIIBE Yutaka <gniibe@fsij.org>
191Date: Sat, 24 Jun 2017 20:46:20 +0900
192Subject: [PATCH 2/5] Same computation for square and multiply.
193
194* mpi/mpi-pow.c (_gcry_mpi_powm): Compare msize for max_u_size. Move
195the assignment to base_u into the loop. Copy content refered by RP to
196BASE_U except the last of the loop.
197
198--
199
200Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
201(backport from master commit:
20278130828e9a140a9de4dafadbc844dbb64cb709a)
203
204Signed-off-by: Ross Burton <ross.burton@intel.com>
205---
206 mpi/mpi-pow.c | 50 +++++++++++++++++++++++++++++---------------------
207 1 file changed, 29 insertions(+), 21 deletions(-)
208
209diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c
210index 7b3dc318..3cba6903 100644
211--- a/mpi/mpi-pow.c
212+++ b/mpi/mpi-pow.c
213@@ -573,6 +573,8 @@ _gcry_mpi_powm (gcry_mpi_t res,
214 MPN_COPY (precomp[i], rp, rsize);
215 }
216
217+ if (msize > max_u_size)
218+ max_u_size = msize;
219 base_u = mpi_alloc_limb_space (max_u_size, esec);
220 MPN_ZERO (base_u, max_u_size);
221
222@@ -619,6 +621,10 @@ _gcry_mpi_powm (gcry_mpi_t res,
223 {
224 int c0;
225 mpi_limb_t e0;
226+ struct gcry_mpi w, u;
227+ w.sign = u.sign = 0;
228+ w.flags = u.flags = 0;
229+ w.d = base_u;
230
231 count_leading_zeros (c0, e);
232 e = (e << c0);
233@@ -652,29 +658,31 @@ _gcry_mpi_powm (gcry_mpi_t res,
234 count_trailing_zeros (c0, e0);
235 e0 = (e0 >> c0) >> 1;
236
237- /*
238- * base_u <= precomp[e0]
239- * base_u_size <= precomp_size[e0]
240- */
241- base_u_size = 0;
242- for (k = 0; k < (1<< (W - 1)); k++)
243- {
244- struct gcry_mpi w, u;
245- w.alloced = w.nlimbs = precomp_size[k];
246- u.alloced = u.nlimbs = precomp_size[k];
247- w.sign = u.sign = 0;
248- w.flags = u.flags = 0;
249- w.d = base_u;
250- u.d = precomp[k];
251-
252- mpi_set_cond (&w, &u, k == e0);
253- base_u_size |= ( precomp_size[k] & ((mpi_size_t)0 - (k == e0)) );
254- }
255-
256 for (j += W - c0; j >= 0; j--)
257 {
258- mul_mod (xp, &xsize, rp, rsize,
259- j == 0 ? base_u : rp, j == 0 ? base_u_size : rsize,
260+
261+ /*
262+ * base_u <= precomp[e0]
263+ * base_u_size <= precomp_size[e0]
264+ */
265+ base_u_size = 0;
266+ for (k = 0; k < (1<< (W - 1)); k++)
267+ {
268+ w.alloced = w.nlimbs = precomp_size[k];
269+ u.alloced = u.nlimbs = precomp_size[k];
270+ u.d = precomp[k];
271+
272+ mpi_set_cond (&w, &u, k == e0);
273+ base_u_size |= ( precomp_size[k] & (0UL - (k == e0)) );
274+ }
275+
276+ w.alloced = w.nlimbs = rsize;
277+ u.alloced = u.nlimbs = rsize;
278+ u.d = rp;
279+ mpi_set_cond (&w, &u, j != 0);
280+ base_u_size ^= ((base_u_size ^ rsize) & (0UL - (j != 0)));
281+
282+ mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size,
283 mp, msize, &karactx);
284 tp = rp; rp = xp; xp = tp;
285 rsize = xsize;
286--
2872.11.0
288
289
290From bf059348dafc1b8d29e07b9426d870ead853db84 Mon Sep 17 00:00:00 2001
291From: NIIBE Yutaka <gniibe@fsij.org>
292Date: Thu, 29 Jun 2017 11:48:44 +0900
293Subject: [PATCH 3/5] rsa: Add exponent blinding.
294
295* cipher/rsa.c (secret): Blind secret D with randomized nonce R for
296mpi_powm computation.
297
298--
299
300Co-authored-by: Werner Koch <wk@gnupg.org>
301Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
302
303The paper describing attack: https://eprint.iacr.org/2017/627
304
305Sliding right into disaster: Left-to-right sliding windows leak
306by Daniel J. Bernstein and Joachim Breitner and Daniel Genkin and
307Leon Groot Bruinderink and Nadia Heninger and Tanja Lange and
308Christine van Vredendaal and Yuval Yarom
309
310 It is well known that constant-time implementations of modular
311 exponentiation cannot use sliding windows. However, software
312 libraries such as Libgcrypt, used by GnuPG, continue to use sliding
313 windows. It is widely believed that, even if the complete pattern of
314 squarings and multiplications is observed through a side-channel
315 attack, the number of exponent bits leaked is not sufficient to
316 carry out a full key-recovery attack against RSA. Specifically,
317 4-bit sliding windows leak only 40% of the bits, and 5-bit sliding
318 windows leak only 33% of the bits.
319
320 In this paper we demonstrate a complete break of RSA-1024 as
321 implemented in Libgcrypt. Our attack makes essential use of the fact
322 that Libgcrypt uses the left-to-right method for computing the
323 sliding-window expansion. We show for the first time that the
324 direction of the encoding matters: the pattern of squarings and
325 multiplications in left-to-right sliding windows leaks significantly
326 more information about exponent bits than for right-to-left. We show
327 how to incorporate this additional information into the
328 Heninger-Shacham algorithm for partial key reconstruction, and use
329 it to obtain very efficient full key recovery for RSA-1024. We also
330 provide strong evidence that the same attack works for RSA-2048 with
331 only moderately more computation.
332
333Exponent blinding is a kind of workaround to add noise. Signal (leak)
334is still there for non-constant-time implementation.
335
336(backported from master commit:
3378725c99ffa41778f382ca97233183bcd687bb0ce)
338
339Signed-off-by: Ross Burton <ross.burton@intel.com>
340---
341 cipher/rsa.c | 32 +++++++++++++++++++++++++-------
342 1 file changed, 25 insertions(+), 7 deletions(-)
343
344diff --git a/cipher/rsa.c b/cipher/rsa.c
345index b6c73741..25e29b5c 100644
346--- a/cipher/rsa.c
347+++ b/cipher/rsa.c
348@@ -1021,15 +1021,33 @@ secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey )
349 gcry_mpi_t m1 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
350 gcry_mpi_t m2 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
351 gcry_mpi_t h = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
352-
353- /* m1 = c ^ (d mod (p-1)) mod p */
354+ gcry_mpi_t D_blind = mpi_alloc_secure ( mpi_get_nlimbs(skey->n) + 1 );
355+ gcry_mpi_t r;
356+ unsigned int r_nbits;
357+
358+ r_nbits = mpi_get_nbits (skey->p) / 4;
359+ if (r_nbits < 96)
360+ r_nbits = 96;
361+ r = mpi_alloc_secure ((r_nbits + BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB);
362+
363+ /* d_blind = (d mod (p-1)) + (p-1) * r */
364+ /* m1 = c ^ d_blind mod p */
365+ _gcry_mpi_randomize (r, r_nbits, GCRY_WEAK_RANDOM);
366+ mpi_set_highbit (r, r_nbits - 1);
367 mpi_sub_ui( h, skey->p, 1 );
368- mpi_fdiv_r( h, skey->d, h );
369- mpi_powm( m1, input, h, skey->p );
370- /* m2 = c ^ (d mod (q-1)) mod q */
371+ mpi_mul ( D_blind, h, r );
372+ mpi_fdiv_r ( h, skey->d, h );
373+ mpi_add ( D_blind, D_blind, h );
374+ mpi_powm( m1, input, D_blind, skey->p );
375+ /* d_blind = (d mod (q-1)) + (q-1) * r */
376+ /* m2 = c ^ d_blind mod q */
377+ _gcry_mpi_randomize (r, r_nbits, GCRY_WEAK_RANDOM);
378+ mpi_set_highbit (r, r_nbits - 1);
379 mpi_sub_ui( h, skey->q, 1 );
380- mpi_fdiv_r( h, skey->d, h );
381- mpi_powm( m2, input, h, skey->q );
382+ mpi_mul ( D_blind, h, r );
383+ mpi_fdiv_r ( h, skey->d, h );
384+ mpi_add ( D_blind, D_blind, h );
385+ mpi_powm( m2, input, D_blind, skey->q );
386 /* h = u * ( m2 - m1 ) mod q */
387 mpi_sub( h, m2, m1 );
388 if ( mpi_has_sign ( h ) )
389--
3902.11.0
391
392
393From 09b9df2675a24e679b7944352ad6385e9e68474f Mon Sep 17 00:00:00 2001
394From: NIIBE Yutaka <gniibe@fsij.org>
395Date: Thu, 29 Jun 2017 12:36:27 +0900
396Subject: [PATCH 4/5] rsa: Fix exponent blinding.
397
398* cipher/rsa.c (secret): Free D_BLIND.
399
400--
401
402Fixes-commit: a9f612def801c8145d551d995475e5d51a4c988c
403Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
404Signed-off-by: Ross Burton <ross.burton@intel.com>
405---
406 cipher/rsa.c | 1 +
407 1 file changed, 1 insertion(+)
408
409diff --git a/cipher/rsa.c b/cipher/rsa.c
410index 25e29b5c..33f92ebd 100644
411--- a/cipher/rsa.c
412+++ b/cipher/rsa.c
413@@ -1057,6 +1057,7 @@ secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey )
414 mpi_mul ( h, h, skey->p );
415 mpi_add ( output, m1, h );
416
417+ mpi_free ( D_blind );
418 mpi_free ( h );
419 mpi_free ( m1 );
420 mpi_free ( m2 );
421--
4222.11.0
423
424
425From 1323fdcf6f2f9fd1da8c5adf396650f15a2a1260 Mon Sep 17 00:00:00 2001
426From: NIIBE Yutaka <gniibe@fsij.org>
427Date: Thu, 29 Jun 2017 12:40:19 +0900
428Subject: [PATCH 5/5] rsa: More fix.
429
430* cipher/rsa.c (secret): Free R.
431
432--
433
434Fixes-commit: a9f612def801c8145d551d995475e5d51a4c988c
435Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
436Signed-off-by: Ross Burton <ross.burton@intel.com>
437---
438 cipher/rsa.c | 1 +
439 1 file changed, 1 insertion(+)
440
441diff --git a/cipher/rsa.c b/cipher/rsa.c
442index 33f92ebd..8d8d157b 100644
443--- a/cipher/rsa.c
444+++ b/cipher/rsa.c
445@@ -1057,6 +1057,7 @@ secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey )
446 mpi_mul ( h, h, skey->p );
447 mpi_add ( output, m1, h );
448
449+ mpi_free ( r );
450 mpi_free ( D_blind );
451 mpi_free ( h );
452 mpi_free ( m1 );
453--
4542.11.0
455
diff --git a/meta/recipes-support/libgcrypt/libgcrypt.inc b/meta/recipes-support/libgcrypt/libgcrypt.inc
index 7c4c0e83b5..00870e3d27 100644
--- a/meta/recipes-support/libgcrypt/libgcrypt.inc
+++ b/meta/recipes-support/libgcrypt/libgcrypt.inc
@@ -21,6 +21,7 @@ SRC_URI = "${GNUPG_MIRROR}/libgcrypt/libgcrypt-${PV}.tar.gz \
21 file://fix-ICE-failure-on-mips-with-option-O-and-g.patch \ 21 file://fix-ICE-failure-on-mips-with-option-O-and-g.patch \
22 file://fix-undefined-reference-to-pthread.patch \ 22 file://fix-undefined-reference-to-pthread.patch \
23 file://0001-ecc-Store-EdDSA-session-key-in-secure-memory.patch \ 23 file://0001-ecc-Store-EdDSA-session-key-in-secure-memory.patch \
24 file://CVE-2017-7526.patch \
24" 25"
25 26
26BINCONFIG = "${bindir}/libgcrypt-config" 27BINCONFIG = "${bindir}/libgcrypt-config"