From e2202ff2b704623efc6277fb5256e4e15bac5676 Mon Sep 17 00:00:00 2001
From: Werner Koch <wk@gnupg.org>
Date: Thu, 25 Jul 2013 11:17:52 +0200
Subject: [PATCH] Mitigate a flush+reload cache attack on RSA secret
 exponents.

commit e2202ff2b704623efc6277fb5256e4e15bac5676 from
git://git.gnupg.org/libgcrypt.git

* mpi/mpi-pow.c (gcry_mpi_powm): Always perfrom the mpi_mul for
exponents in secure memory.

Upstream-Status: Backport

Signed-off-by: Kai Kang <kai.kang@windriver.com>
--

The attack is published as http://eprint.iacr.org/2013/448 :

Flush+Reload: a High Resolution, Low Noise, L3 Cache Side-Channel
Attack by Yuval Yarom and Katrina Falkner. 18 July 2013.

  Flush+Reload is a cache side-channel attack that monitors access to
  data in shared pages. In this paper we demonstrate how to use the
  attack to extract private encryption keys from GnuPG.  The high
  resolution and low noise of the Flush+Reload attack enables a spy
  program to recover over 98% of the bits of the private key in a
  single decryption or signing round. Unlike previous attacks, the
  attack targets the last level L3 cache. Consequently, the spy
  program and the victim do not need to share the execution core of
  the CPU. The attack is not limited to a traditional OS and can be
  used in a virtualised environment, where it can attack programs
  executing in a different VM.

Index: gnupg-1.4.7/mpi/mpi-pow.c
===================================================================
--- gnupg-1.4.7.orig/mpi/mpi-pow.c
+++ gnupg-1.4.7/mpi/mpi-pow.c
@@ -212,7 +212,13 @@ mpi_powm( MPI res, MPI base, MPI exponen
 		tp = rp; rp = xp; xp = tp;
 		rsize = xsize;
 
-		if( (mpi_limb_signed_t)e < 0 ) {
+            /* To mitigate the Yarom/Falkner flush+reload cache
+             * side-channel attack on the RSA secret exponent, we do
+             * the multiplication regardless of the value of the
+             * high-bit of E.  But to avoid this performance penalty
+             * we do it only if the exponent has been stored in secure
+             * memory and we can thus assume it is a secret exponent.  */
+		if (esec || (mpi_limb_signed_t)e < 0) {
 		    /*mpihelp_mul( xp, rp, rsize, bp, bsize );*/
 		    if( bsize < KARATSUBA_THRESHOLD ) {
 			mpihelp_mul( xp, rp, rsize, bp, bsize );
@@ -227,6 +233,8 @@ mpi_powm( MPI res, MPI base, MPI exponen
 			mpihelp_divrem(xp + msize, 0, xp, xsize, mp, msize);
 			xsize = msize;
 		    }
+		}
+		if ( (mpi_limb_signed_t)e < 0 ) {
 
 		    tp = rp; rp = xp; xp = tp;
 		    rsize = xsize;
