diff -Naur gnupg-1.4.14/cipher/dsa.c gnupg-1.4.14.new/cipher/dsa.c
--- gnupg-1.4.14/cipher/dsa.c	2013-07-19 11:37:59.000000000 +0200
+++ gnupg-1.4.14.new/cipher/dsa.c	2014-01-18 08:14:11.473560713 +0100
@@ -274,7 +274,7 @@
 /****************
  * Make a DSA signature from HASH and put it into r and s.
  *
- * Without generating the k this function runs in 
+ * Without generating the k this function runs in
  * about 26ms on a 300 Mhz Mobile Pentium
  */
 
@@ -285,6 +285,8 @@
     MPI kinv;
     MPI tmp;
 
+    mpi_normalize (hash);
+
     /* select a random k with 0 < k < q */
     k = gen_k( skey->q );
 
@@ -311,7 +313,7 @@
 /****************
  * Returns true if the signature composed from R and S is valid.
  *
- * Without the checks this function runs in 
+ * Without the checks this function runs in
  * about 31ms on a 300 Mhz Mobile Pentium
  */
 static int
diff -Naur gnupg-1.4.14/cipher/elgamal.c gnupg-1.4.14.new/cipher/elgamal.c
--- gnupg-1.4.14/cipher/elgamal.c	2013-07-19 11:37:59.000000000 +0200
+++ gnupg-1.4.14.new/cipher/elgamal.c	2014-01-18 08:14:11.474560713 +0100
@@ -374,6 +374,9 @@
 {
     MPI t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) );
 
+    mpi_normalize (a);
+    mpi_normalize (b);
+
     /* output = b/(a^x) mod p */
     mpi_powm( t1, a, skey->x, skey->p );
     mpi_invm( t1, t1, skey->p );
diff -Naur gnupg-1.4.14/cipher/random.c gnupg-1.4.14.new/cipher/random.c
--- gnupg-1.4.14/cipher/random.c	2013-07-19 11:37:59.000000000 +0200
+++ gnupg-1.4.14.new/cipher/random.c	2014-01-18 08:14:11.471560713 +0100
@@ -284,6 +284,18 @@
 }
 
 
+/* Randomize the MPI by setting it to NBITS of random of quality LEVEL.  */
+void
+randomize_mpi (MPI mpi, size_t nbits, int level)
+{
+  unsigned char *buffer;
+
+  buffer = get_random_bits (nbits, level, mpi_is_secure (mpi));
+  mpi_set_buffer (mpi, buffer, (nbits+7)/8, 0);
+  xfree (buffer);
+}
+
+
 int
 random_is_faked()
 {
diff -Naur gnupg-1.4.14/cipher/random.h gnupg-1.4.14.new/cipher/random.h
--- gnupg-1.4.14/cipher/random.h	2013-07-19 11:37:59.000000000 +0200
+++ gnupg-1.4.14.new/cipher/random.h	2014-01-18 08:14:11.471560713 +0100
@@ -30,6 +30,7 @@
 int  random_is_faked(void);
 void random_disable_locking (void);
 void randomize_buffer( byte *buffer, size_t length, int level );
+void randomize_mpi (MPI mpi, size_t nbits, int level);
 byte *get_random_bits( size_t nbits, int level, int secure );
 void fast_random_poll( void );
 
diff -Naur gnupg-1.4.14/cipher/rsa.c gnupg-1.4.14.new/cipher/rsa.c
--- gnupg-1.4.14/cipher/rsa.c	2013-07-19 11:37:59.000000000 +0200
+++ gnupg-1.4.14.new/cipher/rsa.c	2014-01-18 08:14:11.475560713 +0100
@@ -1,5 +1,5 @@
 /* rsa.c  -  RSA function
- *	Copyright (C) 1997, 1998, 1999 by Werner Koch (dd9jn)
+ *	Copyright (C) 1997, 1998, 1999, 2013 by Werner Koch (dd9jn)
  *	Copyright (C) 2000, 2001 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
@@ -22,7 +22,7 @@
    which expires on September 20, 2000.  The patent holder placed that
    patent into the public domain on Sep 6th, 2000.
 */
- 
+
 #include <config.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -32,6 +32,10 @@
 #include "cipher.h"
 #include "rsa.h"
 
+/* Blinding is used to mitigate side-channel attacks.  You may undef
+   this to speed up the operation in case the system is secured
+   against physical and network mounted side-channel attacks.  */
+#define USE_BLINDING 1
 
 typedef struct {
     MPI n;	    /* modulus */
@@ -103,7 +107,7 @@
 
     /* make sure that nbits is even so that we generate p, q of equal size */
     if ( (nbits&1) )
-      nbits++; 
+      nbits++;
 
     n = mpi_alloc ( mpi_nlimb_hint_from_nbits (nbits) );
 
@@ -146,7 +150,7 @@
        65537 as the new best practice.  See FIPS-186-3.
      */
     e = mpi_alloc ( mpi_nlimb_hint_from_nbits (32) );
-    mpi_set_ui( e, 65537); 
+    mpi_set_ui( e, 65537);
     while( !mpi_gcd(t1, e, phi) ) /* (while gcd is not 1) */
       mpi_add_ui( e, e, 2);
 
@@ -268,7 +272,7 @@
     mpi_invm(t, skey->p, skey->q );
     if ( mpi_cmp(t, skey->u ) )
         log_info ( "RSA Oops: u is wrong\n");
-   
+
     log_info ( "RSA secret key check finished\n");
 
     mpi_free (t);
@@ -286,9 +290,9 @@
  *
  * Or faster:
  *
- *      m1 = c ^ (d mod (p-1)) mod p 
- *      m2 = c ^ (d mod (q-1)) mod q 
- *      h = u * (m2 - m1) mod q 
+ *      m1 = c ^ (d mod (p-1)) mod p
+ *      m2 = c ^ (d mod (q-1)) mod q
+ *      h = u * (m2 - m1) mod q
  *      m = m1 + h * p
  *
  * Where m is OUTPUT, c is INPUT and d,n,p,q,u are elements of SKEY.
@@ -299,13 +303,31 @@
 #if 0
     mpi_powm( output, input, skey->d, skey->n );
 #else
-    MPI m1   = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
-    MPI m2   = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
-    MPI h    = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
+    int nlimbs = mpi_get_nlimbs (skey->n)+1;
+    MPI m1   = mpi_alloc_secure (nlimbs);
+    MPI m2   = mpi_alloc_secure (nlimbs);
+    MPI h    = mpi_alloc_secure (nlimbs);
+# ifdef USE_BLINDING
+    MPI bdata= mpi_alloc_secure (nlimbs);
+    MPI r    = mpi_alloc_secure (nlimbs);
+# endif /* USE_BLINDING */
+
+    /* Remove superfluous leading zeroes from INPUT.  */
+    mpi_normalize (input);
+
+# ifdef USE_BLINDING
+    /* Blind:  bdata = (data * r^e) mod n   */
+    randomize_mpi (r, mpi_get_nbits (skey->n), 0);
+    mpi_fdiv_r (r, r, skey->n);
+    mpi_powm (bdata, r, skey->e, skey->n);
+    mpi_mulm (bdata, bdata, input, skey->n);
+    input = bdata;
+# endif /* USE_BLINDING */
 
+    /* RSA secret operation:  */
     /* m1 = c ^ (d mod (p-1)) mod p */
     mpi_sub_ui( h, skey->p, 1  );
-    mpi_fdiv_r( h, skey->d, h );   
+    mpi_fdiv_r( h, skey->d, h );
     mpi_powm( m1, input, h, skey->p );
     /* m2 = c ^ (d mod (q-1)) mod q */
     mpi_sub_ui( h, skey->q, 1  );
@@ -313,14 +335,21 @@
     mpi_powm( m2, input, h, skey->q );
     /* h = u * ( m2 - m1 ) mod q */
     mpi_sub( h, m2, m1 );
-    if ( mpi_is_neg( h ) ) 
+    if ( mpi_is_neg( h ) )
         mpi_add ( h, h, skey->q );
-    mpi_mulm( h, skey->u, h, skey->q ); 
+    mpi_mulm( h, skey->u, h, skey->q );
     /* m = m2 + h * p */
     mpi_mul ( h, h, skey->p );
     mpi_add ( output, m1, h );
-    /* ready */
-    
+
+# ifdef USE_BLINDING
+    mpi_free (bdata);
+    /* Unblind: output = (output * r^(-1)) mod n  */
+    mpi_invm (r, r, skey->n);
+    mpi_mulm (output, output, r, skey->n);
+    mpi_free (r);
+# endif /* USE_BLINDING */
+
     mpi_free ( h );
     mpi_free ( m1 );
     mpi_free ( m2 );
@@ -395,6 +424,7 @@
 rsa_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
 {
     RSA_secret_key sk;
+    MPI input;
 
     if( algo != 1 && algo != 2 )
 	return G10ERR_PUBKEY_ALGO;
@@ -405,8 +435,16 @@
     sk.p = skey[3];
     sk.q = skey[4];
     sk.u = skey[5];
-    *result = mpi_alloc_secure( mpi_get_nlimbs( sk.n ) );
-    secret( *result, data[0], &sk );
+
+    /* Better make sure that there are no superfluous leading zeroes
+       in the input and it has not been padded using multiples of N.
+       This mitigates side-channel attacks (CVE-2013-4576).  */
+    input = mpi_alloc (0);
+    mpi_normalize (data[0]);
+    mpi_fdiv_r (input, data[0], sk.n);
+    *result = mpi_alloc_secure (mpi_get_nlimbs (sk.n));
+    secret (*result, input, &sk);
+    mpi_free (input);
     return 0;
 }
 
diff -Naur gnupg-1.4.14/g10/gpgv.c gnupg-1.4.14.new/g10/gpgv.c
--- gnupg-1.4.14/g10/gpgv.c	2013-07-25 10:37:39.000000000 +0200
+++ gnupg-1.4.14.new/g10/gpgv.c	2014-01-18 08:14:11.473560713 +0100
@@ -389,6 +389,7 @@
 void random_dump_stats(void) {}
 int quick_random_gen( int onoff ) { return -1;}
 void randomize_buffer( byte *buffer, size_t length, int level ) {}
+void randomize_mpi (MPI mpi, size_t nbits, int level) {}
 int random_is_faked() { return -1;}
 byte *get_random_bits( size_t nbits, int level, int secure ) { return NULL;}
 void set_random_seed_file( const char *name ) {}
