1
Description: fix RSA Key Extraction via Low-Bandwidth Acoustic
3
Origin: upstream, http://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=commit;h=93a96e3c0c33370248f6570d8285c4e811d305d4
4
Origin: upstream, http://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=commit;h=d0d72d98f34579213230b3febfebd2fd8dff272b
6
Index: gnupg-1.4.14/cipher/dsa.c
7
===================================================================
8
--- gnupg-1.4.14.orig/cipher/dsa.c 2013-07-19 05:37:59.000000000 -0400
9
+++ gnupg-1.4.14/cipher/dsa.c 2013-12-18 11:08:23.571753942 -0500
12
* Make a DSA signature from HASH and put it into r and s.
14
- * Without generating the k this function runs in
15
+ * Without generating the k this function runs in
16
* about 26ms on a 300 Mhz Mobile Pentium
23
+ mpi_normalize (hash);
25
/* select a random k with 0 < k < q */
30
* Returns true if the signature composed from R and S is valid.
32
- * Without the checks this function runs in
33
+ * Without the checks this function runs in
34
* about 31ms on a 300 Mhz Mobile Pentium
37
Index: gnupg-1.4.14/cipher/elgamal.c
38
===================================================================
39
--- gnupg-1.4.14.orig/cipher/elgamal.c 2013-07-19 05:37:59.000000000 -0400
40
+++ gnupg-1.4.14/cipher/elgamal.c 2013-12-18 11:08:23.571753942 -0500
43
MPI t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) );
48
/* output = b/(a^x) mod p */
49
mpi_powm( t1, a, skey->x, skey->p );
50
mpi_invm( t1, t1, skey->p );
51
Index: gnupg-1.4.14/cipher/random.c
52
===================================================================
53
--- gnupg-1.4.14.orig/cipher/random.c 2013-07-19 05:37:59.000000000 -0400
54
+++ gnupg-1.4.14/cipher/random.c 2013-12-18 11:08:21.159753881 -0500
59
+/* Randomize the MPI by setting it to NBITS of random of quality LEVEL. */
61
+randomize_mpi (MPI mpi, size_t nbits, int level)
63
+ unsigned char *buffer;
65
+ buffer = get_random_bits (nbits, level, mpi_is_secure (mpi));
66
+ mpi_set_buffer (mpi, buffer, (nbits+7)/8, 0);
74
Index: gnupg-1.4.14/cipher/random.h
75
===================================================================
76
--- gnupg-1.4.14.orig/cipher/random.h 2013-07-19 05:37:59.000000000 -0400
77
+++ gnupg-1.4.14/cipher/random.h 2013-12-18 11:08:21.159753881 -0500
79
int random_is_faked(void);
80
void random_disable_locking (void);
81
void randomize_buffer( byte *buffer, size_t length, int level );
82
+void randomize_mpi (MPI mpi, size_t nbits, int level);
83
byte *get_random_bits( size_t nbits, int level, int secure );
84
void fast_random_poll( void );
86
Index: gnupg-1.4.14/cipher/rsa.c
87
===================================================================
88
--- gnupg-1.4.14.orig/cipher/rsa.c 2013-07-19 05:37:59.000000000 -0400
89
+++ gnupg-1.4.14/cipher/rsa.c 2013-12-18 11:08:23.571753942 -0500
91
/* rsa.c - RSA function
92
- * Copyright (C) 1997, 1998, 1999 by Werner Koch (dd9jn)
93
+ * Copyright (C) 1997, 1998, 1999, 2013 by Werner Koch (dd9jn)
94
* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
96
* This file is part of GnuPG.
98
which expires on September 20, 2000. The patent holder placed that
99
patent into the public domain on Sep 6th, 2000.
110
+/* Blinding is used to mitigate side-channel attacks. You may undef
111
+ this to speed up the operation in case the system is secured
112
+ against physical and network mounted side-channel attacks. */
113
+#define USE_BLINDING 1
119
/* make sure that nbits is even so that we generate p, q of equal size */
124
n = mpi_alloc ( mpi_nlimb_hint_from_nbits (nbits) );
127
65537 as the new best practice. See FIPS-186-3.
129
e = mpi_alloc ( mpi_nlimb_hint_from_nbits (32) );
130
- mpi_set_ui( e, 65537);
131
+ mpi_set_ui( e, 65537);
132
while( !mpi_gcd(t1, e, phi) ) /* (while gcd is not 1) */
133
mpi_add_ui( e, e, 2);
136
mpi_invm(t, skey->p, skey->q );
137
if ( mpi_cmp(t, skey->u ) )
138
log_info ( "RSA Oops: u is wrong\n");
141
log_info ( "RSA secret key check finished\n");
148
- * m1 = c ^ (d mod (p-1)) mod p
149
- * m2 = c ^ (d mod (q-1)) mod q
150
- * h = u * (m2 - m1) mod q
151
+ * m1 = c ^ (d mod (p-1)) mod p
152
+ * m2 = c ^ (d mod (q-1)) mod q
153
+ * h = u * (m2 - m1) mod q
156
* Where m is OUTPUT, c is INPUT and d,n,p,q,u are elements of SKEY.
157
@@ -299,13 +303,31 @@
159
mpi_powm( output, input, skey->d, skey->n );
161
- MPI m1 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
162
- MPI m2 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
163
- MPI h = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
164
+ int nlimbs = mpi_get_nlimbs (skey->n)+1;
165
+ MPI m1 = mpi_alloc_secure (nlimbs);
166
+ MPI m2 = mpi_alloc_secure (nlimbs);
167
+ MPI h = mpi_alloc_secure (nlimbs);
168
+# ifdef USE_BLINDING
169
+ MPI bdata= mpi_alloc_secure (nlimbs);
170
+ MPI r = mpi_alloc_secure (nlimbs);
171
+# endif /* USE_BLINDING */
173
+ /* Remove superfluous leading zeroes from INPUT. */
174
+ mpi_normalize (input);
176
+# ifdef USE_BLINDING
177
+ /* Blind: bdata = (data * r^e) mod n */
178
+ randomize_mpi (r, mpi_get_nbits (skey->n), 0);
179
+ mpi_fdiv_r (r, r, skey->n);
180
+ mpi_powm (bdata, r, skey->e, skey->n);
181
+ mpi_mulm (bdata, bdata, input, skey->n);
183
+# endif /* USE_BLINDING */
185
+ /* RSA secret operation: */
186
/* m1 = c ^ (d mod (p-1)) mod p */
187
mpi_sub_ui( h, skey->p, 1 );
188
- mpi_fdiv_r( h, skey->d, h );
189
+ mpi_fdiv_r( h, skey->d, h );
190
mpi_powm( m1, input, h, skey->p );
191
/* m2 = c ^ (d mod (q-1)) mod q */
192
mpi_sub_ui( h, skey->q, 1 );
193
@@ -313,14 +335,21 @@
194
mpi_powm( m2, input, h, skey->q );
195
/* h = u * ( m2 - m1 ) mod q */
196
mpi_sub( h, m2, m1 );
197
- if ( mpi_is_neg( h ) )
198
+ if ( mpi_is_neg( h ) )
199
mpi_add ( h, h, skey->q );
200
- mpi_mulm( h, skey->u, h, skey->q );
201
+ mpi_mulm( h, skey->u, h, skey->q );
203
mpi_mul ( h, h, skey->p );
204
mpi_add ( output, m1, h );
208
+# ifdef USE_BLINDING
210
+ /* Unblind: output = (output * r^(-1)) mod n */
211
+ mpi_invm (r, r, skey->n);
212
+ mpi_mulm (output, output, r, skey->n);
214
+# endif /* USE_BLINDING */
220
rsa_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
225
if( algo != 1 && algo != 2 )
226
return G10ERR_PUBKEY_ALGO;
231
- *result = mpi_alloc_secure( mpi_get_nlimbs( sk.n ) );
232
- secret( *result, data[0], &sk );
234
+ /* Better make sure that there are no superfluous leading zeroes
235
+ in the input and it has not been padded using multiples of N.
236
+ This mitigates side-channel attacks (CVE-2013-4576). */
237
+ input = mpi_alloc (0);
238
+ mpi_normalize (data[0]);
239
+ mpi_fdiv_r (input, data[0], sk.n);
240
+ *result = mpi_alloc_secure (mpi_get_nlimbs (sk.n));
241
+ secret (*result, input, &sk);
246
Index: gnupg-1.4.14/g10/gpgv.c
247
===================================================================
248
--- gnupg-1.4.14.orig/g10/gpgv.c 2013-07-25 04:37:39.000000000 -0400
249
+++ gnupg-1.4.14/g10/gpgv.c 2013-12-18 11:08:21.159753881 -0500
251
void random_dump_stats(void) {}
252
int quick_random_gen( int onoff ) { return -1;}
253
void randomize_buffer( byte *buffer, size_t length, int level ) {}
254
+void randomize_mpi (MPI mpi, size_t nbits, int level) {}
255
int random_is_faked() { return -1;}
256
byte *get_random_bits( size_t nbits, int level, int secure ) { return NULL;}
257
void set_random_seed_file( const char *name ) {}