[git] GCRYPT - branch, LIBGCRYPT-1-5-BRANCH, updated. libgcrypt-1.5.3-11-gf393433

by Werner Koch cvs at cvs.gnupg.org
Thu Aug 7 20:36:30 CEST 2014


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU crypto library".

The branch, LIBGCRYPT-1-5-BRANCH has been updated
       via  f393433a53fde259fbd1d81f2bd1ec19d6463982 (commit)
       via  7235b8d910dfb8fcd19b49c404c62e634c5311c9 (commit)
       via  e2ba3187fc02f0ba0443f0ffc2d13e1fc1aee6c7 (commit)
       via  62e8e1283268f1d3b6d0cfb2fc4e7835bbcdaab6 (commit)
       via  6c3598f1f6a6f2548b60a31ce3c0dd9885558a4f (commit)
      from  2c05a943c5183ca7bfc76115abde29c634198bac (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit f393433a53fde259fbd1d81f2bd1ec19d6463982
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Aug 7 20:33:53 2014 +0200

    Post release updates.
    
    --

diff --git a/NEWS b/NEWS
index adfcecf..dcdd2b9 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+Noteworthy changes in version 1.5.5 (unreleased) [C19/A8/R_]
+------------------------------------------------
+
+
 Noteworthy changes in version 1.5.4 (2014-08-07) [C19/A8/R3]
 ------------------------------------------------
 
diff --git a/configure.ac b/configure.ac
index c8b17ea..8f54c28 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,7 +30,7 @@ min_automake_version="1.11"
 # for the LT versions.
 m4_define(mym4_version_major, [1])
 m4_define(mym4_version_minor, [5])
-m4_define(mym4_version_micro, [4])
+m4_define(mym4_version_micro, [5])
 
 # Below is m4 magic to extract and compute the revision number, the
 # decimalized short revision number, a beta version string, and a flag

commit 7235b8d910dfb8fcd19b49c404c62e634c5311c9
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Aug 7 20:10:39 2014 +0200

    Release 1.5.4.
    
    * configure.ac: Set LT version to C19/A8/R3.

diff --git a/NEWS b/NEWS
index 88c7aea..adfcecf 100644
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,19 @@
-Noteworthy changes in version 1.5.4 (unreleased)
+Noteworthy changes in version 1.5.4 (2014-08-07) [C19/A8/R3]
 ------------------------------------------------
 
-Noteworthy changes in version 1.5.3 (2013-07-25)
+ * Declare 2016-12-31 as end-of-life for 1.5.
+
+ Backported from 1.6:
+
+ * Improved performance of RSA, DSA, and Elgamal by using a new
+   exponentiation algorithm.
+
+ * Fixed a subtle bug in mpi_set_bit which could set spurious bits.
+
+ * Fixed a bug in an internal division function.
+
+
+Noteworthy changes in version 1.5.3 (2013-07-25) [C19/A8/R2]
 ------------------------------------------------
 
  * Mitigate the Yarom/Falkner flush+reload side-channel attack on
diff --git a/configure.ac b/configure.ac
index 00da265..c8b17ea 100644
--- a/configure.ac
+++ b/configure.ac
@@ -59,7 +59,7 @@ AC_INIT([libgcrypt],[mym4_full_version],[http://bugs.gnupg.org])
 #
 LIBGCRYPT_LT_CURRENT=19
 LIBGCRYPT_LT_AGE=8
-LIBGCRYPT_LT_REVISION=2
+LIBGCRYPT_LT_REVISION=3
 
 
 # If the API is changed in an incompatible way: increment the next counter.

commit e2ba3187fc02f0ba0443f0ffc2d13e1fc1aee6c7
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Wed Dec 4 10:03:57 2013 +0900

    mpi: fix gcry_mpi_powm for negative base.
    
    * mpi/mpi-pow.c (gcry_mpi_powm) [USE_ALGORITHM_SIMPLE_EXPONENTIATION]:
    Fix for the case where BASE is negative.
    * tests/mpitests.c (test_powm): Add a test case of (-17)^6 mod 19.
    --
    Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
    (cherry picked from commit c56080c26186d25dec05f01831494c77d8d07e13)
    
    Resolved conflicts:
    	tests/mpitests.c - Use replacements for gcry_mpi_new and
                               gcry_mpi_is_neg.

diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c
index 469c382..4bf0233 100644
--- a/mpi/mpi-pow.c
+++ b/mpi/mpi-pow.c
@@ -177,7 +177,7 @@ gcry_mpi_powm (gcry_mpi_t res,
     }
   MPN_COPY ( rp, bp, bsize );
   rsize = bsize;
-  rsign = bsign;
+  rsign = 0;
 
   /* Main processing.  */
   {
@@ -192,7 +192,7 @@ gcry_mpi_powm (gcry_mpi_t res,
     xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec );
 
     memset( &karactx, 0, sizeof karactx );
-    negative_result = (ep[0] & 1) && base->sign;
+    negative_result = (ep[0] & 1) && bsign;
 
     i = esize - 1;
     e = ep[i];
diff --git a/tests/mpitests.c b/tests/mpitests.c
index cf82842..64ab7a3 100644
--- a/tests/mpitests.c
+++ b/tests/mpitests.c
@@ -181,6 +181,7 @@ test_powm (void)
   int b_int = 17;
   int e_int = 3;
   int m_int = 19;
+  gcry_mpi_t mpi_0 = gcry_mpi_set_ui (NULL, 0);
   gcry_mpi_t base = gcry_mpi_set_ui (NULL, b_int);
   gcry_mpi_t exp = gcry_mpi_set_ui (NULL, e_int);
   gcry_mpi_t mod = gcry_mpi_set_ui (NULL, m_int);
@@ -269,10 +270,31 @@ test_powm (void)
   if (gcry_mpi_cmp (res, base))
     die ("test_powm failed at %d\n", __LINE__);
 
-  /* Fixme: We should add the rest of the cases of course.  */
-
+  /* Check for a case: base is negative and expo is even.  */
+  gcry_mpi_set_ui (base, b_int);
+  gcry_mpi_sub (base, mpi_0, base);
+  gcry_mpi_set_ui (exp, e_int * 2);
+  gcry_mpi_set_ui(mod, m_int);
+  gcry_mpi_powm (res, base, exp, mod);
+  /* Result should be positive and it's 7 = (-17)^6 mod 19.  */
+  if (gcry_mpi_cmp_ui (res, 0) < 0 || gcry_mpi_cmp_ui (res, 7))
+    {
+      if (verbose)
+        {
+          fprintf (stderr, "is_neg: %d\n", (gcry_mpi_cmp_ui (res, 0) < 0));
+          fprintf (stderr, "mpi: ");
+          gcry_mpi_dump (res);
+          putc ('\n', stderr);
+        }
+      die ("test_powm failed for negative base at %d\n", __LINE__);
+    }
 
+  gcry_mpi_release (base);
+  gcry_mpi_release (exp);
+  gcry_mpi_release (mod);
+  gcry_mpi_release (res);
 
+  /* Fixme: We should add the rest of the cases of course.  */
   return 1;
 }
 

commit 62e8e1283268f1d3b6d0cfb2fc4e7835bbcdaab6
Author: NIIBE Yutaka <gniibe at fsij.org>
Date:   Wed Oct 2 09:27:09 2013 +0900

    mpi: mpi-pow improvement.
    
    * mpi/mpi-pow.c (gcry_mpi_powm): New implementation of left-to-right
    k-ary exponentiation.
    --
    
    Signed-off-by: NIIBE Yutaka <gniibe at fsij.org>
    
    For the Yarom/Falkner flush+reload cache side-channel attack, we
    changed the code so that it always calls the multiplication routine
    (even if we can skip it to get result).  This results some performance
    regression.
    
    This change is for recovering performance with efficient algorithm.
    
    (cherry picked from commit 45aa6131e93fac89d46733b3436d960f35fb99b2)

diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c
index 85d6fd8..469c382 100644
--- a/mpi/mpi-pow.c
+++ b/mpi/mpi-pow.c
@@ -34,6 +34,14 @@
 #include "longlong.h"
 
 
+/*
+ * When you need old implementation, please add compilation option
+ * -DUSE_ALGORITHM_SIMPLE_EXPONENTIATION
+ * or expose this line:
+#define USE_ALGORITHM_SIMPLE_EXPONENTIATION 1
+ */
+
+#if defined(USE_ALGORITHM_SIMPLE_EXPONENTIATION)
 /****************
  * RES = BASE ^ EXPO mod MOD
  */
@@ -336,3 +344,449 @@ gcry_mpi_powm (gcry_mpi_t res,
   if (tspace)
     _gcry_mpi_free_limb_space( tspace, 0 );
 }
+#else
+/**
+ * Internal function to compute
+ *
+ *    X = R * S mod M
+ *
+ * and set the size of X at the pointer XSIZE_P.
+ * Use karatsuba structure at KARACTX_P.
+ *
+ * Condition:
+ *   RSIZE >= SSIZE
+ *   Enough space for X is allocated beforehand.
+ *
+ * For generic cases, we can/should use gcry_mpi_mulm.
+ * This function is use for specific internal case.
+ */
+static void
+mul_mod (mpi_ptr_t xp, mpi_size_t *xsize_p,
+         mpi_ptr_t rp, mpi_size_t rsize,
+         mpi_ptr_t sp, mpi_size_t ssize,
+         mpi_ptr_t mp, mpi_size_t msize,
+         struct karatsuba_ctx *karactx_p)
+{
+  if( ssize < KARATSUBA_THRESHOLD )
+    _gcry_mpih_mul ( xp, rp, rsize, sp, ssize );
+  else
+    _gcry_mpih_mul_karatsuba_case (xp, rp, rsize, sp, ssize, karactx_p);
+
+   if (rsize + ssize > msize)
+    {
+      _gcry_mpih_divrem (xp + msize, 0, xp, rsize + ssize, mp, msize);
+      *xsize_p = msize;
+    }
+   else
+     *xsize_p = rsize + ssize;
+}
+
+#define SIZE_B_2I3 ((1 << (5 - 1)) - 1)
+
+/****************
+ * RES = BASE ^ EXPO mod MOD
+ *
+ * To mitigate the Yarom/Falkner flush+reload cache side-channel
+ * attack on the RSA secret exponent, we don't use the square
+ * routine but multiplication.
+ *
+ * Reference:
+ *   Handbook of Applied Cryptography
+ *       Algorithm 14.83: Modified left-to-right k-ary exponentiation
+ */
+void
+gcry_mpi_powm (gcry_mpi_t res,
+               gcry_mpi_t base, gcry_mpi_t expo, gcry_mpi_t mod)
+{
+  /* Pointer to the limbs of the arguments, their size and signs. */
+  mpi_ptr_t  rp, ep, mp, bp;
+  mpi_size_t esize, msize, bsize, rsize;
+  int               msign, bsign, rsign;
+  /* Flags telling the secure allocation status of the arguments.  */
+  int        esec,  msec,  bsec;
+  /* Size of the result including space for temporary values.  */
+  mpi_size_t size;
+  /* Helper.  */
+  int mod_shift_cnt;
+  int negative_result;
+  mpi_ptr_t mp_marker = NULL;
+  mpi_ptr_t bp_marker = NULL;
+  mpi_ptr_t ep_marker = NULL;
+  mpi_ptr_t xp_marker = NULL;
+  unsigned int mp_nlimbs = 0;
+  unsigned int bp_nlimbs = 0;
+  unsigned int ep_nlimbs = 0;
+  unsigned int xp_nlimbs = 0;
+  mpi_ptr_t b_2i3[SIZE_B_2I3]; /* Pre-computed array: BASE^3, ^5, ^7, ... */
+  mpi_size_t b_2i3size[SIZE_B_2I3];
+  mpi_size_t W;
+  mpi_ptr_t base_u;
+  mpi_size_t base_u_size;
+
+  esize = expo->nlimbs;
+  msize = mod->nlimbs;
+  size = 2 * msize;
+  msign = mod->sign;
+
+  if (esize * BITS_PER_MPI_LIMB > 512)
+    W = 5;
+  else if (esize * BITS_PER_MPI_LIMB > 256)
+    W = 4;
+  else if (esize * BITS_PER_MPI_LIMB > 128)
+    W = 3;
+  else if (esize * BITS_PER_MPI_LIMB > 64)
+    W = 2;
+  else
+    W = 1;
+
+  esec = mpi_is_secure(expo);
+  msec = mpi_is_secure(mod);
+  bsec = mpi_is_secure(base);
+
+  rp = res->d;
+  ep = expo->d;
+
+  if (!msize)
+    _gcry_divide_by_zero();
+
+  if (!esize)
+    {
+      /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0 depending
+         on if MOD equals 1.  */
+      res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1;
+      if (res->nlimbs)
+        {
+          RESIZE_IF_NEEDED (res, 1);
+          rp = res->d;
+          rp[0] = 1;
+        }
+      res->sign = 0;
+      goto leave;
+    }
+
+  /* Normalize MOD (i.e. make its most significant bit set) as
+     required by mpn_divrem.  This will make the intermediate values
+     in the calculation slightly larger, but the correct result is
+     obtained after a final reduction using the original MOD value. */
+  mp_nlimbs = msec? msize:0;
+  mp = mp_marker = mpi_alloc_limb_space(msize, msec);
+  count_leading_zeros (mod_shift_cnt, mod->d[msize-1]);
+  if (mod_shift_cnt)
+    _gcry_mpih_lshift (mp, mod->d, msize, mod_shift_cnt);
+  else
+    MPN_COPY( mp, mod->d, msize );
+
+  bsize = base->nlimbs;
+  bsign = base->sign;
+  if (bsize > msize)
+    {
+      /* The base is larger than the module.  Reduce it.
+
+         Allocate (BSIZE + 1) with space for remainder and quotient.
+         (The quotient is (bsize - msize + 1) limbs.)  */
+      bp_nlimbs = bsec ? (bsize + 1):0;
+      bp = bp_marker = mpi_alloc_limb_space( bsize + 1, bsec );
+      MPN_COPY ( bp, base->d, bsize );
+      /* We don't care about the quotient, store it above the
+       * remainder, at BP + MSIZE.  */
+      _gcry_mpih_divrem( bp + msize, 0, bp, bsize, mp, msize );
+      bsize = msize;
+      /* Canonicalize the base, since we are going to multiply with it
+         quite a few times.  */
+      MPN_NORMALIZE( bp, bsize );
+    }
+  else
+    bp = base->d;
+
+  if (!bsize)
+    {
+      res->nlimbs = 0;
+      res->sign = 0;
+      goto leave;
+    }
+
+
+  /* Make BASE, EXPO and MOD not overlap with RES.  */
+  if ( rp == bp )
+    {
+      /* RES and BASE are identical.  Allocate temp. space for BASE.  */
+      gcry_assert (!bp_marker);
+      bp_nlimbs = bsec? bsize:0;
+      bp = bp_marker = mpi_alloc_limb_space( bsize, bsec );
+      MPN_COPY(bp, rp, bsize);
+    }
+  if ( rp == ep )
+    {
+      /* RES and EXPO are identical.  Allocate temp. space for EXPO.  */
+      ep_nlimbs = esec? esize:0;
+      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.*/
+      gcry_assert (!mp_marker);
+      mp_nlimbs = msec?msize:0;
+      mp = mp_marker = mpi_alloc_limb_space( msize, msec );
+      MPN_COPY(mp, rp, msize);
+    }
+
+  /* Copy base to the result.  */
+  if (res->alloced < size)
+    {
+      mpi_resize (res, size);
+      rp = res->d;
+    }
+
+  /* Main processing.  */
+  {
+    mpi_size_t i, j;
+    mpi_ptr_t xp;
+    mpi_size_t xsize;
+    int c;
+    mpi_limb_t e;
+    mpi_limb_t carry_limb;
+    struct karatsuba_ctx karactx;
+    mpi_ptr_t tp;
+
+    xp_nlimbs = msec? (2 * (msize + 1)):0;
+    xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec );
+
+    memset( &karactx, 0, sizeof karactx );
+    negative_result = (ep[0] & 1) && bsign;
+
+    /* Precompute B_2I3[], BASE^(2 * i + 3), BASE^3, ^5, ^7, ... */
+    if (W > 1)                  /* X := BASE^2 */
+      mul_mod (xp, &xsize, bp, bsize, bp, bsize, mp, msize, &karactx);
+    for (i = 0; i < (1 << (W - 1)) - 1; i++)
+      {                         /* B_2I3[i] = BASE^(2 * i + 3) */
+        if (i == 0)
+          {
+            base_u = bp;
+            base_u_size = bsize;
+          }
+        else
+          {
+            base_u = b_2i3[i-1];
+            base_u_size = b_2i3size[i-1];
+          }
+
+        if (xsize >= base_u_size)
+          mul_mod (rp, &rsize, xp, xsize, base_u, base_u_size,
+                   mp, msize, &karactx);
+        else
+          mul_mod (rp, &rsize, base_u, base_u_size, xp, xsize,
+                   mp, msize, &karactx);
+        b_2i3[i] = mpi_alloc_limb_space (rsize, esec);
+        b_2i3size[i] = rsize;
+        MPN_COPY (b_2i3[i], rp, rsize);
+      }
+
+    i = esize - 1;
+
+    /* Main loop.
+
+       Make the result be pointed to alternately by XP and RP.  This
+       helps us avoid block copying, which would otherwise be
+       necessary with the overlap restrictions of
+       _gcry_mpih_divmod. With 50% probability the result after this
+       loop will be in the area originally pointed by RP (==RES->d),
+       and with 50% probability in the area originally pointed to by XP. */
+    rsign = 0;
+    if (W == 1)
+      {
+        rsize = bsize;
+      }
+    else
+      {
+        rsize = msize;
+        MPN_ZERO (rp, rsize);
+      }
+    MPN_COPY ( rp, bp, bsize );
+
+    e = ep[i];
+    count_leading_zeros (c, e);
+    e = (e << c) << 1;
+    c = BITS_PER_MPI_LIMB - 1 - c;
+
+    j = 0;
+
+    for (;;)
+      if (e == 0)
+        {
+          j += c;
+          i--;
+          if ( i < 0 )
+            {
+              c = 0;
+              break;
+            }
+
+          e = ep[i];
+          c = BITS_PER_MPI_LIMB;
+        }
+      else
+        {
+          int c0;
+          mpi_limb_t e0;
+
+          count_leading_zeros (c0, e);
+          e = (e << c0);
+          c -= c0;
+          j += c0;
+
+          if (c >= W)
+            {
+              e0 = (e >> (BITS_PER_MPI_LIMB - W));
+              e = (e << W);
+              c -= W;
+            }
+          else
+            {
+              i--;
+              if ( i < 0 )
+                {
+                  e = (e >> (BITS_PER_MPI_LIMB - c));
+                  break;
+                }
+
+              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;
+            }
+
+          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;
+            }
+
+          if (e0 == 0)
+            {
+              base_u = bp;
+              base_u_size = bsize;
+            }
+          else
+            {
+              base_u = b_2i3[e0 - 1];
+              base_u_size = b_2i3size[e0 -1];
+            }
+
+          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 (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);
+        tp = rp; rp = xp; xp = tp;
+        rsize = xsize;
+      }
+
+    if (e != 0)
+      {
+        if ((e>>1) == 0)
+          {
+            base_u = bp;
+            base_u_size = bsize;
+          }
+        else
+          {
+            base_u = b_2i3[(e>>1) - 1];
+            base_u_size = b_2i3size[(e>>1) -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.
+
+       Also make sure the result is put in RES->d (where it already
+       might be, see above).  */
+    if ( mod_shift_cnt )
+      {
+        carry_limb = _gcry_mpih_lshift( res->d, rp, rsize, mod_shift_cnt);
+        rp = res->d;
+        if ( carry_limb )
+          {
+            rp[rsize] = carry_limb;
+            rsize++;
+          }
+      }
+    else if (res->d != rp)
+      {
+        MPN_COPY (res->d, rp, rsize);
+        rp = res->d;
+      }
+
+    if ( rsize >= msize )
+      {
+        _gcry_mpih_divrem(rp + msize, 0, rp, rsize, mp, msize);
+        rsize = msize;
+      }
+
+    /* Remove any leading zero words from the result.  */
+    if ( mod_shift_cnt )
+      _gcry_mpih_rshift( rp, rp, rsize, mod_shift_cnt);
+    MPN_NORMALIZE (rp, rsize);
+
+    _gcry_mpih_release_karatsuba_ctx (&karactx );
+    for (i = 0; i < (1 << (W - 1)) - 1; i++)
+      _gcry_mpi_free_limb_space( b_2i3[i], esec ? b_2i3size[i] : 0 );
+  }
+
+  /* Fixup for negative results.  */
+  if ( negative_result && rsize )
+    {
+      if ( mod_shift_cnt )
+        _gcry_mpih_rshift( mp, mp, msize, mod_shift_cnt);
+      _gcry_mpih_sub( rp, mp, msize, rp, rsize);
+      rsize = msize;
+      rsign = msign;
+      MPN_NORMALIZE(rp, rsize);
+    }
+  gcry_assert (res->d == rp);
+  res->nlimbs = rsize;
+  res->sign = rsign;
+
+ leave:
+  if (mp_marker)
+    _gcry_mpi_free_limb_space( mp_marker, mp_nlimbs );
+  if (bp_marker)
+    _gcry_mpi_free_limb_space( bp_marker, bp_nlimbs );
+  if (ep_marker)
+    _gcry_mpi_free_limb_space( ep_marker, ep_nlimbs );
+  if (xp_marker)
+    _gcry_mpi_free_limb_space( xp_marker, xp_nlimbs );
+}
+#endif

commit 6c3598f1f6a6f2548b60a31ce3c0dd9885558a4f
Author: Xi Wang <xi.wang at gmail.com>
Date:   Tue Aug 14 18:54:40 2012 -0400

    Replace deliberate division by zero with _gcry_divide_by_zero.
    
    * mpi/mpi-pow.c: Replace 1 / msize.
    * mpi/mpih-div.c: Replace 1 / dsize.
    * src/misc.c: Add _gcry_divide_by_zero.
    --
    
    1) Division by zero doesn't "provoke a signal" on architectures
       like PowerPC.
    
    2) C compilers like clang will optimize away these divisions, even
       though the code tries "to make the compiler not remove" them.
    
    This patch redirects these cases to _gcry_divide_by_zero.
    
    (cherry picked from commit 2c54c4da19d3a79e9f749740828026dd41f0521a)

diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c
index a63fc6d..85d6fd8 100644
--- a/mpi/mpi-pow.c
+++ b/mpi/mpi-pow.c
@@ -77,7 +77,7 @@ gcry_mpi_powm (gcry_mpi_t res,
   ep = expo->d;
 
   if (!msize)
-    msize = 1 / msize;	    /* Provoke a signal.  */
+    _gcry_divide_by_zero();
 
   if (!esize)
     {
diff --git a/mpi/mpih-div.c b/mpi/mpih-div.c
index 224b810..b33dcbf 100644
--- a/mpi/mpih-div.c
+++ b/mpi/mpih-div.c
@@ -212,9 +212,8 @@ _gcry_mpih_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs,
 
     switch(dsize) {
       case 0:
-	/* We are asked to divide by zero, so go ahead and do it!  (To make
-	   the compiler not remove this statement, return the value.)  */
-	return 1 / dsize;
+	_gcry_divide_by_zero();
+	break;
 
       case 1:
 	{
diff --git a/src/g10lib.h b/src/g10lib.h
index 30706a2..9e017b1 100644
--- a/src/g10lib.h
+++ b/src/g10lib.h
@@ -101,6 +101,8 @@ void _gcry_bug (const char *file, int line);
 void _gcry_assert_failed (const char *expr, const char *file, int line);
 #endif
 
+void _gcry_divide_by_zero (void) JNLIB_GCC_A_NR;
+
 const char *_gcry_gettext (const char *key) GCC_ATTR_FORMAT_ARG(1);
 void _gcry_fatal_error(int rc, const char *text ) JNLIB_GCC_A_NR;
 void _gcry_log( int level, const char *fmt, ... ) JNLIB_GCC_A_PRINTF(2,3);
diff --git a/src/misc.c b/src/misc.c
index 17bd546..ed72ed6 100644
--- a/src/misc.c
+++ b/src/misc.c
@@ -19,6 +19,7 @@
  */
 
 #include <config.h>
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -296,3 +297,10 @@ _gcry_burn_stack (int bytes)
     if (bytes > 0)
         _gcry_burn_stack (bytes);
 }
+
+void
+_gcry_divide_by_zero (void)
+{
+    gpg_err_set_errno (EDOM);
+    _gcry_fatal_error (gpg_err_code_from_errno (errno), "divide by zero");
+}

-----------------------------------------------------------------------

Summary of changes:
 NEWS             |   20 ++-
 configure.ac     |    4 +-
 mpi/mpi-pow.c    |  460 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 mpi/mpih-div.c   |    5 +-
 src/g10lib.h     |    2 +
 src/misc.c       |    8 +
 tests/mpitests.c |   26 ++-
 7 files changed, 513 insertions(+), 12 deletions(-)


hooks/post-receive
-- 
The GNU crypto library
http://git.gnupg.org




More information about the Gnupg-commits mailing list