~ubuntu-branches/ubuntu/vivid/gnupg/vivid

« back to all changes in this revision

Viewing changes to debian/patches/CVE-2013-4576

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2013-12-20 08:17:09 UTC
  • mfrom: (1.1.23 sid)
  • Revision ID: package-import@ubuntu.com-20131220081709-uylvbzvk4m7dej37
Tags: 1.4.15-2ubuntu1
* Resynchronise with Debian.  Remaining changes:
  - Disable mlock() test since it fails with ulimit 0 (on buildds).
  - Set gpg (or gpg2) and gpgsm to use a passphrase agent by default.
  - Only suggest gnupg-curl and libldap; recommendations are pulled into
    minimal, and we don't need the keyserver utilities in a minimal Ubuntu
    system.
  - Remove the Win32 build.
  - Build using dh-autoreconf
  - Disable inline assembler for ppc64el.
* Moved CVE-2013-4576 patch to the right directory, and added to series
  file so it actually gets applied.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Description: fix RSA Key Extraction via Low-Bandwidth Acoustic
 
2
 Cryptanalysis attack
 
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
 
5
 
 
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
 
10
@@ -274,7 +274,7 @@
 
11
 /****************
 
12
  * Make a DSA signature from HASH and put it into r and s.
 
13
  *
 
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
 
17
  */
 
18
 
 
19
@@ -285,6 +285,8 @@
 
20
     MPI kinv;
 
21
     MPI tmp;
 
22
 
 
23
+    mpi_normalize (hash);
 
24
+
 
25
     /* select a random k with 0 < k < q */
 
26
     k = gen_k( skey->q );
 
27
 
 
28
@@ -311,7 +313,7 @@
 
29
 /****************
 
30
  * Returns true if the signature composed from R and S is valid.
 
31
  *
 
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
 
35
  */
 
36
 static int
 
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
 
41
@@ -374,6 +374,9 @@
 
42
 {
 
43
     MPI t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) );
 
44
 
 
45
+    mpi_normalize (a);
 
46
+    mpi_normalize (b);
 
47
+
 
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
 
55
@@ -284,6 +284,18 @@
 
56
 }
 
57
 
 
58
 
 
59
+/* Randomize the MPI by setting it to NBITS of random of quality LEVEL.  */
 
60
+void
 
61
+randomize_mpi (MPI mpi, size_t nbits, int level)
 
62
+{
 
63
+  unsigned char *buffer;
 
64
+
 
65
+  buffer = get_random_bits (nbits, level, mpi_is_secure (mpi));
 
66
+  mpi_set_buffer (mpi, buffer, (nbits+7)/8, 0);
 
67
+  xfree (buffer);
 
68
+}
 
69
+
 
70
+
 
71
 int
 
72
 random_is_faked()
 
73
 {
 
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
 
78
@@ -30,6 +30,7 @@
 
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 );
 
85
 
 
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
 
90
@@ -1,5 +1,5 @@
 
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.
 
95
  *
 
96
  * This file is part of GnuPG.
 
97
@@ -22,7 +22,7 @@
 
98
    which expires on September 20, 2000.  The patent holder placed that
 
99
    patent into the public domain on Sep 6th, 2000.
 
100
 */
 
101
 
102
+
 
103
 #include <config.h>
 
104
 #include <stdio.h>
 
105
 #include <stdlib.h>
 
106
@@ -32,6 +32,10 @@
 
107
 #include "cipher.h"
 
108
 #include "rsa.h"
 
109
 
 
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
 
114
 
 
115
 typedef struct {
 
116
     MPI n;         /* modulus */
 
117
@@ -103,7 +107,7 @@
 
118
 
 
119
     /* make sure that nbits is even so that we generate p, q of equal size */
 
120
     if ( (nbits&1) )
 
121
-      nbits++; 
 
122
+      nbits++;
 
123
 
 
124
     n = mpi_alloc ( mpi_nlimb_hint_from_nbits (nbits) );
 
125
 
 
126
@@ -146,7 +150,7 @@
 
127
        65537 as the new best practice.  See FIPS-186-3.
 
128
      */
 
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);
 
134
 
 
135
@@ -268,7 +272,7 @@
 
136
     mpi_invm(t, skey->p, skey->q );
 
137
     if ( mpi_cmp(t, skey->u ) )
 
138
         log_info ( "RSA Oops: u is wrong\n");
 
139
-   
 
140
+
 
141
     log_info ( "RSA secret key check finished\n");
 
142
 
 
143
     mpi_free (t);
 
144
@@ -286,9 +290,9 @@
 
145
  *
 
146
  * Or faster:
 
147
  *
 
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
 
154
  *      m = m1 + h * p
 
155
  *
 
156
  * Where m is OUTPUT, c is INPUT and d,n,p,q,u are elements of SKEY.
 
157
@@ -299,13 +303,31 @@
 
158
 #if 0
 
159
     mpi_powm( output, input, skey->d, skey->n );
 
160
 #else
 
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 */
 
172
+
 
173
+    /* Remove superfluous leading zeroes from INPUT.  */
 
174
+    mpi_normalize (input);
 
175
+
 
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);
 
182
+    input = bdata;
 
183
+# endif /* USE_BLINDING */
 
184
 
 
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 );
 
202
     /* m = m2 + h * p */
 
203
     mpi_mul ( h, h, skey->p );
 
204
     mpi_add ( output, m1, h );
 
205
-    /* ready */
 
206
-    
 
207
+
 
208
+# ifdef USE_BLINDING
 
209
+    mpi_free (bdata);
 
210
+    /* Unblind: output = (output * r^(-1)) mod n  */
 
211
+    mpi_invm (r, r, skey->n);
 
212
+    mpi_mulm (output, output, r, skey->n);
 
213
+    mpi_free (r);
 
214
+# endif /* USE_BLINDING */
 
215
+
 
216
     mpi_free ( h );
 
217
     mpi_free ( m1 );
 
218
     mpi_free ( m2 );
 
219
@@ -395,6 +424,7 @@
 
220
 rsa_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
 
221
 {
 
222
     RSA_secret_key sk;
 
223
+    MPI input;
 
224
 
 
225
     if( algo != 1 && algo != 2 )
 
226
        return G10ERR_PUBKEY_ALGO;
 
227
@@ -405,8 +435,16 @@
 
228
     sk.p = skey[3];
 
229
     sk.q = skey[4];
 
230
     sk.u = skey[5];
 
231
-    *result = mpi_alloc_secure( mpi_get_nlimbs( sk.n ) );
 
232
-    secret( *result, data[0], &sk );
 
233
+
 
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);
 
242
+    mpi_free (input);
 
243
     return 0;
 
244
 }
 
245
 
 
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
 
250
@@ -389,6 +389,7 @@
 
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 ) {}