[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [pkg-gnupg-maint] Fixing CVE-2017-7526 in for wheezy / jessie



Hi Niibe-san,
On Tue, Aug 29, 2017 at 09:57:51AM +0900, NIIBE Yutaka wrote:
> Hello, Guido,
> 
> Guido Günther <agx@sigxcpu.org> wrote:
> > I just looked into fixing CVE-2017-7526 for gnupg in wheezy. Based on
> > https://dev.gnupg.org/D438 I backported what I deemed are the necessary
> > patches. Does this look sane? 
> 
> I'm not GnuPG package maintainers, but one of upstream developers.
> For me, it look sane.
> 
> Let me explain patches, just in case.
> 
> For GnuPG 2.0 and 2.1, it is fixed by libgcrypt.  In case of GnuPG 1.4,
> it is fixed in 1.4.22.
> 
> For CVE-2017-7526, what we did is two things.
> 
> (1) Same computation
> 
>     It's by the commit:
>     12029f83fd0a
>     mpi: Same computation for square and multiply for mpi_pow.
> 
> (2) Exponent blinding
> 
>     It's D438.
> 
> The intention of (1) is to minimize the information to side channel(s).
> The intention of (2) is to maximize the noise to side channel(s).
> 
> Either of (1) or (2) (or both) can mitigate the attack.  My own response
> was (1)-only, but the authors of the paper suggested (2) is recommended.

Thank you _very_ much for the detailed review! Since we can have (1) and
(2) in Wheezy / Jessie I decided to pull in the mpi_pow stuff as well. A
new debdiff is attached.

Thanks again for caring about gnupg 1.4.
Cheers,
 -- Guido
diff --git a/debian/changelog b/debian/changelog
index adf00944..d6848d64 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+gnupg (1.4.12-7+deb7u9) wheezy-security; urgency=medium
+
+  * Backport fixes for CVE-2017-7526 from STABLE-BRANCH-1-4 branch
+
+ -- Guido Günther <agx@sigxcpu.org>  Mon, 28 Aug 2017 11:59:38 +0200
+
 gnupg (1.4.12-7+deb7u8) wheezy-security; urgency=high
 
   * Non-maintainer upload by the Debian LTS Team.
diff --git a/debian/patches/security/CVE-2017-7526-mpi-Minor-fix-for-mpi_pow.patch b/debian/patches/security/CVE-2017-7526-mpi-Minor-fix-for-mpi_pow.patch
new file mode 100644
index 00000000..251dc319
--- /dev/null
+++ b/debian/patches/security/CVE-2017-7526-mpi-Minor-fix-for-mpi_pow.patch
@@ -0,0 +1,34 @@
+From: NIIBE Yutaka <gniibe@fsij.org>
+Date: Fri, 7 Jul 2017 15:12:00 +0900
+Subject: CVE-2017-7526: mpi: Minor fix for mpi_pow.
+
+* mpi/mpi-pow.c (mpi_powm): Fix allocation size.
+
+Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
+(cherry picked from commit 554ded4854758bf6ca268432fa087f946932a409)
+---
+ mpi/mpi-pow.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c
+index acddca9..0078b84 100644
+--- a/mpi/mpi-pow.c
++++ b/mpi/mpi-pow.c
+@@ -162,7 +162,7 @@ mpi_powm( MPI res, MPI base, MPI exponent, MPI mod)
+ 
+     {
+ 	mpi_size_t i;
+-	mpi_ptr_t xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec );
++	mpi_ptr_t xp = xp_marker = mpi_alloc_limb_space( size, msec );
+ 	int c;
+ 	mpi_limb_t e;
+ 	mpi_limb_t carry_limb;
+@@ -499,7 +499,7 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod)
+     struct karatsuba_ctx karactx;
+     mpi_ptr_t tp;
+ 
+-    xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec );
++    xp = xp_marker = mpi_alloc_limb_space( size, msec );
+ 
+     memset( &karactx, 0, sizeof karactx );
+     negative_result = (ep[0] & 1) && bsign;
diff --git a/debian/patches/security/CVE-2017-7526-mpi-Same-computation-for-square-and-multipl.patch b/debian/patches/security/CVE-2017-7526-mpi-Same-computation-for-square-and-multipl.patch
new file mode 100644
index 00000000..88639b1d
--- /dev/null
+++ b/debian/patches/security/CVE-2017-7526-mpi-Same-computation-for-square-and-multipl.patch
@@ -0,0 +1,165 @@
+From: NIIBE Yutaka <gniibe@fsij.org>
+Date: Fri, 7 Jul 2017 14:38:19 +0900
+Subject: CVE-2017-7526: mpi: Same computation for square and multiply for
+ mpi_pow.
+
+* mpi/mpi-pow.c (_gcry_mpi_powm): Compare msize for max_u_size.  Move
+the assignment to base_u into the loop.  Copy content refered by RP to
+BASE_U except the last of the loop.
+
+--
+
+Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
+
+(backport commit of libgcrypt master:
+78130828e9a140a9de4dafadbc844dbb64cb709a)
+
+(cherry picked from commit 12029f83fd0ab3e8ad524f6c9135854662fddfd1)
+---
+ mpi/mpi-pow.c | 72 +++++++++++++++++++++++++++++++----------------------------
+ 1 file changed, 38 insertions(+), 34 deletions(-)
+
+diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c
+index 76ddf95..acddca9 100644
+--- a/mpi/mpi-pow.c
++++ b/mpi/mpi-pow.c
+@@ -387,6 +387,9 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod)
+   size = 2 * msize;
+   msign = mod->sign;
+ 
++  ep = expo->d;
++  MPN_NORMALIZE(ep, esize);
++
+   if (esize * BITS_PER_MPI_LIMB > 512)
+     W = 5;
+   else if (esize * BITS_PER_MPI_LIMB > 256)
+@@ -403,10 +406,9 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod)
+   bsec = mpi_is_secure(base);
+ 
+   rp = res->d;
+-  ep = expo->d;
+ 
+   if (!msize)
+-     msize = 1 / msize;	    /* provoke a signal */
++    msize = 1 / msize;	    /* provoke a signal */
+ 
+   if (!esize)
+     {
+@@ -463,7 +465,8 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod)
+     }
+ 
+ 
+-  /* Make BASE, EXPO and MOD not overlap with RES.  */
++  /* Make BASE, EXPO not overlap with RES.  We don't need to check MOD
++     because that has already been copied to the MP var.  */
+   if ( rp == bp )
+     {
+       /* RES and BASE are identical.  Allocate temp. space for BASE.  */
+@@ -477,13 +480,6 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod)
+       ep = ep_marker = mpi_alloc_limb_space( esize, esec );
+       MPN_COPY(ep, rp, esize);
+     }
+-  if ( rp == mp )
+-    {
+-      /* RES and MOD are identical.  Allocate temporary space for MOD.*/
+-      assert (!mp_marker);
+-      mp = mp_marker = mpi_alloc_limb_space( msize, msec );
+-      MPN_COPY(mp, rp, msize);
+-    }
+ 
+   /* Copy base to the result.  */
+   if (res->alloced < size)
+@@ -529,7 +525,10 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod)
+         MPN_COPY (precomp[i], rp, rsize);
+       }
+ 
++    if (msize > max_u_size)
++      max_u_size = msize;
+     base_u = mpi_alloc_limb_space (max_u_size, esec);
++    MPN_ZERO (base_u, max_u_size);
+ 
+     i = esize - 1;
+ 
+@@ -574,6 +573,10 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod)
+         {
+           int c0;
+           mpi_limb_t e0;
++          struct gcry_mpi w, u;
++          w.sign = u.sign = 0;
++          w.flags = u.flags = 0;
++          w.d = base_u;
+ 
+           count_leading_zeros (c0, e);
+           e = (e << c0);
+@@ -582,7 +585,7 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod)
+ 
+           e0 = (e >> (BITS_PER_MPI_LIMB - W));
+           if (c >= W)
+-            c0 =0;
++            c0 = 0;
+           else
+             {
+               if ( --i < 0 )
+@@ -597,7 +600,7 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod)
+                   e = ep[i];
+                   c = BITS_PER_MPI_LIMB;
+                   e0 |= (e >> (BITS_PER_MPI_LIMB - (W - c0)));
+-               }
++		}
+             }
+ 
+           e = e << (W - c0);
+@@ -607,30 +610,31 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod)
+           count_trailing_zeros (c0, e0);
+           e0 = (e0 >> c0) >> 1;
+ 
+-          /*
+-           *  base_u <= precomp[e0]
+-           *  base_u_size <= precomp_size[e0];
+-           */
+-          base_u_size = 0;
+-          for (k = 0; k < (1<< (W - 1)); k++)
+-            {
+-              struct gcry_mpi w, u;
+-              w.alloced = w.nlimbs = precomp_size[k];
+-              u.alloced = u.nlimbs = precomp_size[k];
+-              w.nbits = w.nlimbs * BITS_PER_MPI_LIMB;
+-              u.nbits = u.nlimbs * BITS_PER_MPI_LIMB;
+-              w.sign = u.sign = 0;
+-              w.flags = u.flags = 0;
+-              w.d = base_u;
+-              u.d = precomp[k];
+-
+-              mpi_set_cond (&w, &u, k == e0);
+-              base_u_size |= ( precomp_size[k] & ((mpi_size_t)0 - (k == e0)) );
+-            }
+           for (j += W - c0; j >= 0; j--)
+             {
+-              mul_mod (xp, &xsize, rp, rsize,
+-                       j == 0 ? base_u : rp, j == 0 ? base_u_size : rsize,
++
++              /*
++               *  base_u <= precomp[e0]
++               *  base_u_size <= precomp_size[e0]
++               */
++              base_u_size = 0;
++              for (k = 0; k < (1<< (W - 1)); k++)
++                {
++                  w.alloced = w.nlimbs = precomp_size[k];
++                  u.alloced = u.nlimbs = precomp_size[k];
++                  u.d = precomp[k];
++
++                  mpi_set_cond (&w, &u, k == e0);
++                  base_u_size |= ( precomp_size[k] & (0UL - (k == e0)) );
++                }
++
++              w.alloced = w.nlimbs = rsize;
++              u.alloced = u.nlimbs = rsize;
++              u.d = rp;
++              mpi_set_cond (&w, &u, j != 0);
++              base_u_size ^= ((base_u_size ^ rsize)  & (0UL - (j != 0)));
++
++              mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size,
+                        mp, msize, &karactx);
+               tp = rp; rp = xp; xp = tp;
+               rsize = xsize;
diff --git a/debian/patches/security/CVE-2017-7526-mpi-Simplify-mpi_powm.patch b/debian/patches/security/CVE-2017-7526-mpi-Simplify-mpi_powm.patch
new file mode 100644
index 00000000..749fa65d
--- /dev/null
+++ b/debian/patches/security/CVE-2017-7526-mpi-Simplify-mpi_powm.patch
@@ -0,0 +1,167 @@
+From: NIIBE Yutaka <gniibe@fsij.org>
+Date: Fri, 7 Jul 2017 14:26:39 +0900
+Subject: CVE-2017-7526: mpi: Simplify mpi_powm.
+
+* mpi/mpi-pow.c (_gcry_mpi_powm): Simplify the loop.
+
+--
+
+(backport of libgcrypt master commit:
+ 719468e53133d3bdf12156c5bfdea2bf15f9f6f1)
+
+Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
+(cherry picked from commit b38f4489f75e6e435886aa885807738a22c7ff60)
+---
+ mpi/mpi-pow.c | 103 +++++++++++++++++-----------------------------------------
+ 1 file changed, 30 insertions(+), 73 deletions(-)
+
+diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c
+index 7f23a5a..76ddf95 100644
+--- a/mpi/mpi-pow.c
++++ b/mpi/mpi-pow.c
+@@ -564,12 +564,8 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod)
+       if (e == 0)
+         {
+           j += c;
+-          i--;
+-          if ( i < 0 )
+-            {
+-              c = 0;
+-              break;
+-            }
++          if ( --i < 0 )
++            break;
+ 
+           e = ep[i];
+           c = BITS_PER_MPI_LIMB;
+@@ -584,38 +580,33 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod)
+           c -= c0;
+           j += c0;
+ 
++          e0 = (e >> (BITS_PER_MPI_LIMB - W));
+           if (c >= W)
+-            {
+-              e0 = (e >> (BITS_PER_MPI_LIMB - W));
+-              e = (e << W);
+-              c -= W;
+-            }
++            c0 =0;
+           else
+             {
+-              i--;
+-              if ( i < 0 )
++              if ( --i < 0 )
+                 {
+-                  e = (e >> (BITS_PER_MPI_LIMB - c));
+-                  break;
++                  e0 = (e >> (BITS_PER_MPI_LIMB - c));
++                  j += c - W;
++                  goto last_step;
+                 }
+-
+-              c0 = c;
+-              e0 = (e >> (BITS_PER_MPI_LIMB - W))
+-                | (ep[i] >> (BITS_PER_MPI_LIMB - W + c0));
+-              e = (ep[i] << (W - c0));
+-              c = BITS_PER_MPI_LIMB - W + c0;
++              else
++                {
++                  c0 = c;
++                  e = ep[i];
++                  c = BITS_PER_MPI_LIMB;
++                  e0 |= (e >> (BITS_PER_MPI_LIMB - (W - c0)));
++               }
+             }
+ 
++          e = e << (W - c0);
++          c -= (W - c0);
++
++        last_step:
+           count_trailing_zeros (c0, e0);
+           e0 = (e0 >> c0) >> 1;
+ 
+-          for (j += W - c0; j; j--)
+-            {
+-              mul_mod (xp, &xsize, rp, rsize, rp, rsize, mp, msize, &karactx);
+-              tp = rp; rp = xp; xp = tp;
+-              rsize = xsize;
+-            }
+-
+           /*
+            *  base_u <= precomp[e0]
+            *  base_u_size <= precomp_size[e0];
+@@ -634,24 +625,22 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod)
+               u.d = precomp[k];
+ 
+               mpi_set_cond (&w, &u, k == e0);
+-              base_u_size |= (precomp_size[k] & ((mpi_size_t)0 - (k == e0)) );
++              base_u_size |= ( precomp_size[k] & ((mpi_size_t)0 - (k == e0)) );
++            }
++          for (j += W - c0; j >= 0; j--)
++            {
++              mul_mod (xp, &xsize, rp, rsize,
++                       j == 0 ? base_u : rp, j == 0 ? base_u_size : rsize,
++                       mp, msize, &karactx);
++              tp = rp; rp = xp; xp = tp;
++              rsize = xsize;
+             }
+-          mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size,
+-                   mp, msize, &karactx);
+-          tp = rp; rp = xp; xp = tp;
+-          rsize = xsize;
+ 
+           j = c0;
++          if ( i < 0 )
++            break;
+         }
+ 
+-    if (c != 0)
+-      {
+-        j += c;
+-        count_trailing_zeros (c, e);
+-        e = (e >> c);
+-        j -= c;
+-      }
+-
+     while (j--)
+       {
+         mul_mod (xp, &xsize, rp, rsize, rp, rsize, mp, msize, &karactx);
+@@ -659,38 +648,6 @@ mpi_powm (MPI res, MPI base, MPI expo, MPI mod)
+         rsize = xsize;
+       }
+ 
+-    if (e != 0)
+-      {
+-        base_u_size = 0;
+-        for (k = 0; k < (1<< (W - 1)); k++)
+-          {
+-            struct gcry_mpi w, u;
+-            w.alloced = w.nlimbs = precomp_size[k];
+-            u.alloced = u.nlimbs = precomp_size[k];
+-            w.nbits = w.nlimbs * BITS_PER_MPI_LIMB;
+-            u.nbits = u.nlimbs * BITS_PER_MPI_LIMB;
+-            w.sign = u.sign = 0;
+-            w.flags = u.flags = 0;
+-            w.d = base_u;
+-            u.d = precomp[k];
+-
+-            mpi_set_cond (&w, &u, k == (e>>1));
+-            base_u_size |= (precomp_size[k] & ((mpi_size_t)0 - (k == (e>>1))) );
+-          }
+-
+-        mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size,
+-                 mp, msize, &karactx);
+-        tp = rp; rp = xp; xp = tp;
+-        rsize = xsize;
+-
+-        for (; c; c--)
+-          {
+-            mul_mod (xp, &xsize, rp, rsize, rp, rsize, mp, msize, &karactx);
+-            tp = rp; rp = xp; xp = tp;
+-            rsize = xsize;
+-          }
+-      }
+-
+     /* We shifted MOD, the modulo reduction argument, left
+        MOD_SHIFT_CNT steps.  Adjust the result by reducing it with the
+        original MOD.
diff --git a/debian/patches/security/CVE-2017-7526-rsa-Add-exponent-blinding.patch b/debian/patches/security/CVE-2017-7526-rsa-Add-exponent-blinding.patch
new file mode 100644
index 00000000..9c98ca5f
--- /dev/null
+++ b/debian/patches/security/CVE-2017-7526-rsa-Add-exponent-blinding.patch
@@ -0,0 +1,71 @@
+From: Marcus Brinkmann <mb@g10code.com>
+Date: Fri, 7 Jul 2017 21:03:10 +0900
+Subject: CVE-2017-7526: rsa: Add exponent blinding.
+
+* cipher/rsa.c (secret_core_crt): Blind secret D with randomized
+nonce R for mpi_powm computation.
+
+--
+
+Backport of libgcrypt 8725c99ffa41778f382ca97233183bcd687bb0ce.
+
+Signed-off-by: Marcus Brinkmann <mb@g10code.com>
+---
+ cipher/rsa.c | 33 +++++++++++++++++++++++++++++----
+ 1 file changed, 29 insertions(+), 4 deletions(-)
+
+diff --git a/cipher/rsa.c b/cipher/rsa.c
+index c4d5161..78a6f87 100644
+--- a/cipher/rsa.c
++++ b/cipher/rsa.c
+@@ -29,6 +29,7 @@
+ #include <string.h>
+ #include "util.h"
+ #include "mpi.h"
++#include "../mpi/mpi-internal.h"
+ #include "cipher.h"
+ #include "rsa.h"
+ 
+@@ -325,14 +326,38 @@ secret(MPI output, MPI input, RSA_secret_key *skey )
+ # endif /* USE_BLINDING */
+ 
+     /* RSA secret operation:  */
+-    /* m1 = c ^ (d mod (p-1)) mod p */
++    MPI D_blind = mpi_alloc_secure (nlimbs);
++    MPI rr;
++    unsigned int rr_nbits;
++
++    rr_nbits = mpi_get_nbits (skey->p) / 4;
++    if (rr_nbits < 96)
++      rr_nbits = 96;
++    rr = mpi_alloc_secure ( (rr_nbits + BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
++
++    /* d_blind = (d mod (p-1)) + (p-1) * r            */
++    /* m1 = c ^ d_blind mod p */
++    randomize_mpi (rr, rr_nbits, 0);
++    mpi_set_highbit (rr, rr_nbits - 1);
+     mpi_sub_ui( h, skey->p, 1  );
++    mpi_mul ( D_blind, h, rr );
+     mpi_fdiv_r( h, skey->d, h );
+-    mpi_powm( m1, input, h, skey->p );
+-    /* m2 = c ^ (d mod (q-1)) mod q */
++    mpi_add ( D_blind, D_blind, h );
++    mpi_powm ( m1, input, D_blind, skey->p );
++
++    /* d_blind = (d mod (q-1)) + (q-1) * r            */
++    /* m2 = c ^ d_blind mod q */
++    randomize_mpi (rr, rr_nbits, 0);
++    mpi_set_highbit (rr, rr_nbits - 1);
+     mpi_sub_ui( h, skey->q, 1  );
++    mpi_mul ( D_blind, h, rr );
+     mpi_fdiv_r( h, skey->d, h );
+-    mpi_powm( m2, input, h, skey->q );
++    mpi_add ( D_blind, D_blind, h );
++    mpi_powm ( m2, input, D_blind, skey->q );
++
++    mpi_free ( rr );
++    mpi_free ( D_blind );
++
+     /* h = u * ( m2 - m1 ) mod q */
+     mpi_sub( h, m2, m1 );
+     if ( mpi_is_neg( h ) )
diff --git a/debian/patches/security/CVE-2017-7526-rsa-Allow-different-build-directory.patch b/debian/patches/security/CVE-2017-7526-rsa-Allow-different-build-directory.patch
new file mode 100644
index 00000000..c66ad3dd
--- /dev/null
+++ b/debian/patches/security/CVE-2017-7526-rsa-Allow-different-build-directory.patch
@@ -0,0 +1,53 @@
+From: NIIBE Yutaka <gniibe@fsij.org>
+Date: Fri, 7 Jul 2017 21:20:56 +0900
+Subject: CVE-2017-7526: rsa: Allow different build directory.
+
+* cipher/Makefile.am (AM_CPPFLAGS): Add mpi dirs.
+* cipher/rsa.c: Change include file.
+
+Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
+---
+ cipher/Makefile.am | 2 +-
+ cipher/Makefile.in | 2 +-
+ cipher/rsa.c       | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/cipher/Makefile.am b/cipher/Makefile.am
+index a10af20..92ffe90 100644
+--- a/cipher/Makefile.am
++++ b/cipher/Makefile.am
+@@ -17,7 +17,7 @@
+ # along with this program; if not, see <http://www.gnu.org/licenses/>.
+ ## Process this file with automake to produce Makefile.in
+ 
+-AM_CPPFLAGS = -I.. -I$(top_srcdir)/include -I$(top_srcdir)/intl
++AM_CPPFLAGS = -I.. -I$(top_srcdir)/include -I$(top_srcdir)/intl -I$(top_srcdir)/mpi -I../mpi
+ 
+ if ! HAVE_DOSISH_SYSTEM
+ AM_CPPFLAGS += -DGNUPG_LIBDIR="\"$(libdir)/@PACKAGE@\""
+diff --git a/cipher/Makefile.in b/cipher/Makefile.in
+index a2a3fd1..6238cbb 100644
+--- a/cipher/Makefile.in
++++ b/cipher/Makefile.in
+@@ -299,7 +299,7 @@ target_alias = @target_alias@
+ top_build_prefix = @top_build_prefix@
+ top_builddir = @top_builddir@
+ top_srcdir = @top_srcdir@
+-AM_CPPFLAGS = -I.. -I$(top_srcdir)/include -I$(top_srcdir)/intl \
++AM_CPPFLAGS = -I.. -I$(top_srcdir)/include -I$(top_srcdir)/intl -I$(top_srcdir)/mpi -I../mpi \
+ 	$(am__append_1)
+ noinst_LIBRARIES = libcipher.a
+ libcipher_a_SOURCES = cipher.c pubkey.c md.c dynload.c bithelp.h des.c \
+diff --git a/cipher/rsa.c b/cipher/rsa.c
+index 78a6f87..f454992 100644
+--- a/cipher/rsa.c
++++ b/cipher/rsa.c
+@@ -29,7 +29,7 @@
+ #include <string.h>
+ #include "util.h"
+ #include "mpi.h"
+-#include "../mpi/mpi-internal.h"
++#include "mpi-internal.h"
+ #include "cipher.h"
+ #include "rsa.h"
+ 
diff --git a/debian/patches/security/CVE-2017-7526-rsa-Reduce-secmem-pressure.patch b/debian/patches/security/CVE-2017-7526-rsa-Reduce-secmem-pressure.patch
new file mode 100644
index 00000000..b338c360
--- /dev/null
+++ b/debian/patches/security/CVE-2017-7526-rsa-Reduce-secmem-pressure.patch
@@ -0,0 +1,46 @@
+From: NIIBE Yutaka <gniibe@fsij.org>
+Date: Fri, 7 Jul 2017 21:51:42 +0900
+Subject: CVE-2017-7526: rsa: Reduce secmem pressure.
+
+* cipher/rsa.c (secret): Don't keep secmem.
+
+Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
+---
+ cipher/rsa.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/cipher/rsa.c b/cipher/rsa.c
+index f454992..5894713 100644
+--- a/cipher/rsa.c
++++ b/cipher/rsa.c
+@@ -341,22 +341,29 @@ secret(MPI output, MPI input, RSA_secret_key *skey )
+     mpi_set_highbit (rr, rr_nbits - 1);
+     mpi_sub_ui( h, skey->p, 1  );
+     mpi_mul ( D_blind, h, rr );
++    mpi_free ( rr );
+     mpi_fdiv_r( h, skey->d, h );
+     mpi_add ( D_blind, D_blind, h );
++    mpi_free ( h );
+     mpi_powm ( m1, input, D_blind, skey->p );
+ 
++    h = mpi_alloc_secure (nlimbs);
++    rr = mpi_alloc_secure ( (rr_nbits + BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
++
+     /* d_blind = (d mod (q-1)) + (q-1) * r            */
+     /* m2 = c ^ d_blind mod q */
+     randomize_mpi (rr, rr_nbits, 0);
+     mpi_set_highbit (rr, rr_nbits - 1);
+     mpi_sub_ui( h, skey->q, 1  );
+     mpi_mul ( D_blind, h, rr );
++    mpi_free ( rr );
+     mpi_fdiv_r( h, skey->d, h );
+     mpi_add ( D_blind, D_blind, h );
++    mpi_free ( h );
+     mpi_powm ( m2, input, D_blind, skey->q );
+ 
+-    mpi_free ( rr );
+     mpi_free ( D_blind );
++    h = mpi_alloc_secure (nlimbs);
+ 
+     /* h = u * ( m2 - m1 ) mod q */
+     mpi_sub( h, m2, m1 );
diff --git a/debian/patches/series b/debian/patches/series
index dc95e2c5..4ce5e6db 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -17,3 +17,9 @@ CVE-2015-1606.patch
 0001-g10-Fix-checking-key-for-signature-validation.patch
 0046-cipher-Improve-readability-by-using-a-macro.patch
 0047-random-Hash-continuous-areas-in-the-csprng-pool.patch
+security/CVE-2017-7526-rsa-Add-exponent-blinding.patch
+security/CVE-2017-7526-rsa-Allow-different-build-directory.patch
+security/CVE-2017-7526-rsa-Reduce-secmem-pressure.patch
+security/CVE-2017-7526-mpi-Simplify-mpi_powm.patch
+security/CVE-2017-7526-mpi-Same-computation-for-square-and-multipl.patch
+security/CVE-2017-7526-mpi-Minor-fix-for-mpi_pow.patch

Reply to: