svn commit: r296465 - in releng/9.3: . crypto/openssl crypto/openssl/apps crypto/openssl/bugs crypto/openssl/crypto crypto/openssl/crypto/aes crypto/openssl/crypto/asn1 crypto/openssl/crypto/bf cry...

Xin Li delphij at delphij.net
Wed Mar 9 09:16:54 UTC 2016


FYI -- I can confirm that libcrypto is broken and have a reliable way to
trigger it.

So far I was able to narrow down this to this change and here is a
temporary workaround (which will reintroduce CVE-2016-0702).

Cheers,
-------------- next part --------------
Index: crypto/openssl/crypto/bn/bn.h
===================================================================
--- crypto/openssl/crypto/bn/bn.h	(revision 296556)
+++ crypto/openssl/crypto/bn/bn.h	(working copy)
@@ -69,13 +69,13 @@
  *
  */
 
-#ifndef HEADER_BN_H
-# define HEADER_BN_H
-
-# include <limits.h>
-# include <openssl/e_os2.h>
-# ifndef OPENSSL_NO_FP_API
-#  include <stdio.h>            /* FILE */
+#ifndef HEADER_BN_H
+# define HEADER_BN_H
+
+# include <limits.h>
+# include <openssl/e_os2.h>
+# ifndef OPENSSL_NO_FP_API
+#  include <stdio.h>            /* FILE */
 # endif
 # include <openssl/ossl_typ.h>
 
@@ -702,23 +702,23 @@ const BIGNUM *BN_get0_nist_prime_224(void);
 const BIGNUM *BN_get0_nist_prime_256(void);
 const BIGNUM *BN_get0_nist_prime_384(void);
 const BIGNUM *BN_get0_nist_prime_521(void);
-
-/* library internal functions */
-
-# define bn_expand(a,bits) \
-    ( \
-        bits > (INT_MAX - BN_BITS2 + 1) ? \
-            NULL \
-        : \
-            (((bits+BN_BITS2-1)/BN_BITS2) <= (a)->dmax) ? \
-                (a) \
-            : \
-                bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2) \
-    )
-
-# define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
-BIGNUM *bn_expand2(BIGNUM *a, int words);
-# ifndef OPENSSL_NO_DEPRECATED
+
+/* library internal functions */
+
+# define bn_expand(a,bits) \
+    ( \
+        bits > (INT_MAX - BN_BITS2 + 1) ? \
+            NULL \
+        : \
+            (((bits+BN_BITS2-1)/BN_BITS2) <= (a)->dmax) ? \
+                (a) \
+            : \
+                bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2) \
+    )
+
+# define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
+BIGNUM *bn_expand2(BIGNUM *a, int words);
+# ifndef OPENSSL_NO_DEPRECATED
 BIGNUM *bn_dup_expand(const BIGNUM *a, int words); /* unused */
 # endif
 
Index: crypto/openssl/crypto/bn/bn_exp.c
===================================================================
--- crypto/openssl/crypto/bn/bn_exp.c	(revision 296556)
+++ crypto/openssl/crypto/bn/bn_exp.c	(working copy)
@@ -107,13 +107,12 @@
  * (eay at cryptsoft.com).  This product includes software written by Tim
  * Hudson (tjh at cryptsoft.com).
  *
- */
-
-#include "cryptlib.h"
-#include "constant_time_locl.h"
-#include "bn_lcl.h"
-
-/* maximum precomputation table size for *variable* sliding windows */
+ */
+
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+/* maximum precomputation table size for *variable* sliding windows */
 #define TABLE_SIZE      32
 
 /* this one works - simple but works */
@@ -521,79 +520,41 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, c
  * pattern as far as cache lines are concerned.  The following functions are
  * used to transfer a BIGNUM from/to that table.
  */
-
-static int MOD_EXP_CTIME_COPY_TO_PREBUF(BIGNUM *b, int top,
-                                        unsigned char *buf, int idx,
-                                        int window)
-{
-    int i, j;
-    int width = 1 << window;
-    BN_ULONG *table = (BN_ULONG *)buf;
-
-    if (bn_wexpand(b, top) == NULL)
-        return 0;
+
+static int MOD_EXP_CTIME_COPY_TO_PREBUF(BIGNUM *b, int top,
+                                        unsigned char *buf, int idx,
+                                        int width)
+{
+    size_t i, j;
+
+    if (bn_wexpand(b, top) == NULL)
+        return 0;
     while (b->top < top) {
-        b->d[b->top++] = 0;
-    }
-
-    for (i = 0, j = idx; i < top; i++, j += width) {
-        table[j] = b->d[i];
-    }
-
-    bn_correct_top(b);
+        b->d[b->top++] = 0;
+    }
+
+    for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) {
+        buf[j] = ((unsigned char *)b->d)[i];
+    }
+
+    bn_correct_top(b);
     return 1;
 }
-
-static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top,
-                                          unsigned char *buf, int idx,
-                                          int window)
-{
-    int i, j;
-    int width = 1 << window;
-    volatile BN_ULONG *table = (volatile BN_ULONG *)buf;
-
-    if (bn_wexpand(b, top) == NULL)
-        return 0;
-
-    if (window <= 3) {
-        for (i = 0; i < top; i++, table += width) {
-            BN_ULONG acc = 0;
-
-            for (j = 0; j < width; j++) {
-                acc |= table[j] &
-                       ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1));
-            }
-
-            b->d[i] = acc;
-        }
-    } else {
-        int xstride = 1 << (window - 2);
-        BN_ULONG y0, y1, y2, y3;
-
-        i = idx >> (window - 2);        /* equivalent of idx / xstride */
-        idx &= xstride - 1;             /* equivalent of idx % xstride */
-
-        y0 = (BN_ULONG)0 - (constant_time_eq_int(i,0)&1);
-        y1 = (BN_ULONG)0 - (constant_time_eq_int(i,1)&1);
-        y2 = (BN_ULONG)0 - (constant_time_eq_int(i,2)&1);
-        y3 = (BN_ULONG)0 - (constant_time_eq_int(i,3)&1);
-
-        for (i = 0; i < top; i++, table += width) {
-            BN_ULONG acc = 0;
-
-            for (j = 0; j < xstride; j++) {
-                acc |= ( (table[j + 0 * xstride] & y0) |
-                         (table[j + 1 * xstride] & y1) |
-                         (table[j + 2 * xstride] & y2) |
-                         (table[j + 3 * xstride] & y3) )
-                       & ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1));
-            }
-
-            b->d[i] = acc;
-        }
-    }
-
-    b->top = top;
+
+static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top,
+                                          unsigned char *buf, int idx,
+                                          int width)
+{
+    size_t i, j;
+
+    if (bn_wexpand(b, top) == NULL)
+        return 0;
+
+    for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) {
+        ((unsigned char *)b->d)[i] = buf[j];
+    }
+
+    b->top = top;
     bn_correct_top(b);
     return 1;
 }
@@ -684,13 +645,13 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BI
     /*
      * Initialize the intermediate result. Do this early to save double
      * conversion, once each for a^0 and intermediate result.
-     */
-    if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
-        goto err;
-    if (!MOD_EXP_CTIME_COPY_TO_PREBUF(r, top, powerbuf, 0, window))
-        goto err;
-
-    /* Initialize computeTemp as a^1 with montgomery precalcs */
+     */
+    if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
+        goto err;
+    if (!MOD_EXP_CTIME_COPY_TO_PREBUF(r, top, powerbuf, 0, numPowers))
+        goto err;
+
+    /* Initialize computeTemp as a^1 with montgomery precalcs */
     computeTemp = BN_CTX_get(ctx);
     am = BN_CTX_get(ctx);
     if (computeTemp == NULL || am == NULL)
@@ -703,13 +664,13 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BI
     } else
         aa = a;
     if (!BN_to_montgomery(am, aa, mont, ctx))
-        goto err;
-    if (!BN_copy(computeTemp, am))
-        goto err;
-    if (!MOD_EXP_CTIME_COPY_TO_PREBUF(am, top, powerbuf, 1, window))
-        goto err;
-
-    /*
+        goto err;
+    if (!BN_copy(computeTemp, am))
+        goto err;
+    if (!MOD_EXP_CTIME_COPY_TO_PREBUF(am, top, powerbuf, 1, numPowers))
+        goto err;
+
+    /*
      * If the window size is greater than 1, then calculate
      * val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1) (even powers
      * could instead be computed as (a^(i/2))^2 to use the slight performance
@@ -718,14 +679,14 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BI
     if (window > 1) {
         for (i = 2; i < numPowers; i++) {
             /* Calculate a^i = a^(i-1) * a */
-            if (!BN_mod_mul_montgomery
-                (computeTemp, am, computeTemp, mont, ctx))
-                goto err;
-            if (!MOD_EXP_CTIME_COPY_TO_PREBUF(computeTemp, top, powerbuf, i,
-                                              window))
-                goto err;
-        }
-    }
+            if (!BN_mod_mul_montgomery
+                (computeTemp, am, computeTemp, mont, ctx))
+                goto err;
+            if (!MOD_EXP_CTIME_COPY_TO_PREBUF
+                (computeTemp, top, powerbuf, i, numPowers))
+                goto err;
+        }
+    }
 
     /*
      * Adjust the number of bits up to a multiple of the window size. If the
Index: crypto/openssl/crypto/bn/bn_print.c
===================================================================
--- crypto/openssl/crypto/bn/bn_print.c	(revision 296556)
+++ crypto/openssl/crypto/bn/bn_print.c	(working copy)
@@ -55,14 +55,14 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
-
-#include <stdio.h>
-#include <ctype.h>
-#include <limits.h>
-#include "cryptlib.h"
-#include <openssl/buffer.h>
-#include "bn_lcl.h"
 
+#include <stdio.h>
+#include <ctype.h>
+#include <limits.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+#include "bn_lcl.h"
+
 static const char Hex[] = "0123456789ABCDEF";
 
 /* Must 'OPENSSL_free' the returned data */
@@ -187,19 +187,19 @@ int BN_hex2bn(BIGNUM **bn, const char *a)
 
     if (*a == '-') {
         neg = 1;
-        a++;
-    }
-
-    for (i = 0; i <= (INT_MAX/4) && isxdigit((unsigned char)a[i]); i++)
-        continue;
-
-    if (i > INT_MAX/4)
-        goto err;
-
-    num = i + neg;
-    if (bn == NULL)
-        return (num);
+        a++;
+    }
 
+    for (i = 0; i <= (INT_MAX/4) && isxdigit((unsigned char)a[i]); i++)
+        continue;
+
+    if (i > INT_MAX/4)
+        goto err;
+
+    num = i + neg;
+    if (bn == NULL)
+        return (num);
+
     /* a is the start of the hex digits, and it is 'i' long */
     if (*bn == NULL) {
         if ((ret = BN_new()) == NULL)
@@ -206,13 +206,13 @@ int BN_hex2bn(BIGNUM **bn, const char *a)
             return (0);
     } else {
         ret = *bn;
-        BN_zero(ret);
-    }
-
-    /* i is the number of hex digits */
-    if (bn_expand(ret, i * 4) == NULL)
-        goto err;
-
+        BN_zero(ret);
+    }
+
+    /* i is the number of hex digits */
+    if (bn_expand(ret, i * 4) == NULL)
+        goto err;
+
     j = i;                      /* least significant 'hex' */
     m = 0;
     h = 0;
@@ -262,19 +262,19 @@ int BN_dec2bn(BIGNUM **bn, const char *a)
         return (0);
     if (*a == '-') {
         neg = 1;
-        a++;
-    }
-
-    for (i = 0; i <= (INT_MAX/4) && isdigit((unsigned char)a[i]); i++)
-        continue;
-
-    if (i > INT_MAX/4)
-        goto err;
-
-    num = i + neg;
-    if (bn == NULL)
-        return (num);
+        a++;
+    }
 
+    for (i = 0; i <= (INT_MAX/4) && isdigit((unsigned char)a[i]); i++)
+        continue;
+
+    if (i > INT_MAX/4)
+        goto err;
+
+    num = i + neg;
+    if (bn == NULL)
+        return (num);
+
     /*
      * a is the start of the digits, and it is 'i' long. We chop it into
      * BN_DEC_NUM digits at a time
@@ -284,13 +284,13 @@ int BN_dec2bn(BIGNUM **bn, const char *a)
             return (0);
     } else {
         ret = *bn;
-        BN_zero(ret);
-    }
-
-    /* i is the number of digits, a bit of an over expand */
-    if (bn_expand(ret, i * 4) == NULL)
-        goto err;
-
+        BN_zero(ret);
+    }
+
+    /* i is the number of digits, a bit of an over expand */
+    if (bn_expand(ret, i * 4) == NULL)
+        goto err;
+
     j = BN_DEC_NUM - (i % BN_DEC_NUM);
     if (j == BN_DEC_NUM)
         j = 0;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: OpenPGP digital signature
URL: <http://lists.freebsd.org/pipermail/svn-src-all/attachments/20160309/f40e01ce/attachment.sig>


More information about the svn-src-all mailing list