Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 7 Mar 2016 16:18:07 +0000 (UTC)
From:      Xin LI <delphij@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r296462 - in stable/9: crypto/openssl/crypto/bio crypto/openssl/crypto/bn crypto/openssl/doc/apps crypto/openssl/ssl secure/usr.bin/openssl/man
Message-ID:  <201603071618.u27GI736079901@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: delphij
Date: Mon Mar  7 16:18:07 2016
New Revision: 296462
URL: https://svnweb.freebsd.org/changeset/base/296462

Log:
  Fix multiple OpenSSL vulnerabilities as published in
  OpenSSL advisory on 2016/03/01:
  
  constant-time MOD_EXP_CTIME_COPY_FROM_PREBUF.
  [CVE-2016-0702, upstream d6482a8. 5ea08bd, d6d422e,
  8fc8f48 317be63 skipped intentionally as we are not
  using the code on FreeBSD.  Backport done by jkim@.
  
  Fix memory issues in BIO_*printf functions.
  [CVE-2016-0799, upstream d889682, a801bf2].
  
  Fix BN_hex2bn/BN_dec2bn NULL ptr/heap corruption.
  [CVE-2016-0797, upstream 8f65132].
  
  Disable SSLv2 in default negotiation and weak ciphers.
  [CVE-2016-0800 "DROWN", upstream 56f1acf5].  Note that
  support of SSLv2 is not removed in order to preserve
  ABI compatibility, and application may still explicitly
  ask for vulnerable protocol or ciphers.
  
  In collaboration with: jkim

Modified:
  stable/9/crypto/openssl/crypto/bio/b_print.c
  stable/9/crypto/openssl/crypto/bn/bn.h
  stable/9/crypto/openssl/crypto/bn/bn_exp.c
  stable/9/crypto/openssl/crypto/bn/bn_print.c
  stable/9/crypto/openssl/doc/apps/ciphers.pod
  stable/9/crypto/openssl/ssl/s2_lib.c
  stable/9/crypto/openssl/ssl/ssl_lib.c
  stable/9/secure/usr.bin/openssl/man/ciphers.1

Modified: stable/9/crypto/openssl/crypto/bio/b_print.c
==============================================================================
--- stable/9/crypto/openssl/crypto/bio/b_print.c	Mon Mar  7 16:13:54 2016	(r296461)
+++ stable/9/crypto/openssl/crypto/bio/b_print.c	Mon Mar  7 16:18:07 2016	(r296462)
@@ -122,20 +122,20 @@
 #  define LLONG long long
 # endif
 #else
-# define LLONG long
-#endif
-
-static void fmtstr(char **, char **, size_t *, size_t *,
-                   const char *, int, int, int);
-static void fmtint(char **, char **, size_t *, size_t *,
-                   LLONG, int, int, int, int);
-static void fmtfp(char **, char **, size_t *, size_t *,
-                  LDOUBLE, int, int, int);
-static void doapr_outch(char **, char **, size_t *, size_t *, int);
-static void _dopr(char **sbuffer, char **buffer,
-                  size_t *maxlen, size_t *retlen, int *truncated,
-                  const char *format, va_list args);
-
+# define LLONG long
+#endif
+
+static int fmtstr(char **, char **, size_t *, size_t *,
+                   const char *, int, int, int);
+static int fmtint(char **, char **, size_t *, size_t *,
+                   LLONG, int, int, int, int);
+static int fmtfp(char **, char **, size_t *, size_t *,
+                  LDOUBLE, int, int, int);
+static int doapr_outch(char **, char **, size_t *, size_t *, int);
+static int _dopr(char **sbuffer, char **buffer,
+                  size_t *maxlen, size_t *retlen, int *truncated,
+                  const char *format, va_list args);
+
 /* format read states */
 #define DP_S_DEFAULT    0
 #define DP_S_FLAGS      1
@@ -162,13 +162,13 @@ static void _dopr(char **sbuffer, char *
 #define DP_C_LLONG      4
 
 /* some handy macros */
-#define char_to_int(p) (p - '0')
-#define OSSL_MAX(p,q) ((p >= q) ? p : q)
-
-static void
-_dopr(char **sbuffer,
-      char **buffer,
-      size_t *maxlen,
+#define char_to_int(p) (p - '0')
+#define OSSL_MAX(p,q) ((p >= q) ? p : q)
+
+static int
+_dopr(char **sbuffer,
+      char **buffer,
+      size_t *maxlen,
       size_t *retlen, int *truncated, const char *format, va_list args)
 {
     char ch;
@@ -193,13 +193,14 @@ _dopr(char **sbuffer,
 
         switch (state) {
         case DP_S_DEFAULT:
-            if (ch == '%')
-                state = DP_S_FLAGS;
-            else
-                doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
-            ch = *format++;
-            break;
-        case DP_S_FLAGS:
+            if (ch == '%')
+                state = DP_S_FLAGS;
+            else
+                if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
+                    return 0;
+            ch = *format++;
+            break;
+        case DP_S_FLAGS:
             switch (ch) {
             case '-':
                 flags |= DP_F_MINUS;
@@ -299,14 +300,15 @@ _dopr(char **sbuffer,
                     value = va_arg(args, LLONG);
                     break;
                 default:
-                    value = va_arg(args, int);
-                    break;
-                }
-                fmtint(sbuffer, buffer, &currlen, maxlen,
-                       value, 10, min, max, flags);
-                break;
-            case 'X':
-                flags |= DP_F_UP;
+                    value = va_arg(args, int);
+                    break;
+                }
+                if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, 10, min,
+                            max, flags))
+                    return 0;
+                break;
+            case 'X':
+                flags |= DP_F_UP;
                 /* FALLTHROUGH */
             case 'x':
             case 'o':
@@ -323,23 +325,25 @@ _dopr(char **sbuffer,
                     value = va_arg(args, unsigned LLONG);
                     break;
                 default:
-                    value = (LLONG) va_arg(args, unsigned int);
-                    break;
-                }
-                fmtint(sbuffer, buffer, &currlen, maxlen, value,
-                       ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
-                       min, max, flags);
-                break;
-            case 'f':
-                if (cflags == DP_C_LDOUBLE)
-                    fvalue = va_arg(args, LDOUBLE);
-                else
-                    fvalue = va_arg(args, double);
-                fmtfp(sbuffer, buffer, &currlen, maxlen,
-                      fvalue, min, max, flags);
-                break;
-            case 'E':
-                flags |= DP_F_UP;
+                    value = (LLONG) va_arg(args, unsigned int);
+                    break;
+                }
+                if (!fmtint(sbuffer, buffer, &currlen, maxlen, value,
+                       ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
+                            min, max, flags))
+                    return 0;
+                break;
+            case 'f':
+                if (cflags == DP_C_LDOUBLE)
+                    fvalue = va_arg(args, LDOUBLE);
+                else
+                    fvalue = va_arg(args, double);
+                if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max,
+                           flags))
+                    return 0;
+                break;
+            case 'E':
+                flags |= DP_F_UP;
             case 'e':
                 if (cflags == DP_C_LDOUBLE)
                     fvalue = va_arg(args, LDOUBLE);
@@ -352,30 +356,33 @@ _dopr(char **sbuffer,
                 if (cflags == DP_C_LDOUBLE)
                     fvalue = va_arg(args, LDOUBLE);
                 else
-                    fvalue = va_arg(args, double);
-                break;
-            case 'c':
-                doapr_outch(sbuffer, buffer, &currlen, maxlen,
-                            va_arg(args, int));
-                break;
-            case 's':
-                strvalue = va_arg(args, char *);
+                    fvalue = va_arg(args, double);
+                break;
+            case 'c':
+                if(!doapr_outch(sbuffer, buffer, &currlen, maxlen,
+                            va_arg(args, int)))
+                    return 0;
+                break;
+            case 's':
+                strvalue = va_arg(args, char *);
                 if (max < 0) {
                     if (buffer)
                         max = INT_MAX;
-                    else
-                        max = *maxlen;
-                }
-                fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
-                       flags, min, max);
-                break;
-            case 'p':
-                value = (long)va_arg(args, void *);
-                fmtint(sbuffer, buffer, &currlen, maxlen,
-                       value, 16, min, max, flags | DP_F_NUM);
-                break;
-            case 'n':          /* XXX */
-                if (cflags == DP_C_SHORT) {
+                    else
+                        max = *maxlen;
+                }
+                if (!fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
+                            flags, min, max))
+                    return 0;
+                break;
+            case 'p':
+                value = (long)va_arg(args, void *);
+                if (!fmtint(sbuffer, buffer, &currlen, maxlen,
+                            value, 16, min, max, flags | DP_F_NUM))
+                    return 0;
+                break;
+            case 'n':          /* XXX */
+                if (cflags == DP_C_SHORT) {
                     short int *num;
                     num = va_arg(args, short int *);
                     *num = currlen;
@@ -391,13 +398,14 @@ _dopr(char **sbuffer,
                     int *num;
                     num = va_arg(args, int *);
                     *num = currlen;
-                }
-                break;
-            case '%':
-                doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
-                break;
-            case 'w':
-                /* not supported yet, treat as next char */
+                }
+                break;
+            case '%':
+                if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch))
+                    return 0;
+                break;
+            case 'w':
+                /* not supported yet, treat as next char */
                 ch = *format++;
                 break;
             default:
@@ -415,52 +423,62 @@ _dopr(char **sbuffer,
             break;
         }
     }
-    *truncated = (currlen > *maxlen - 1);
-    if (*truncated)
-        currlen = *maxlen - 1;
-    doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0');
-    *retlen = currlen - 1;
-    return;
-}
-
-static void
-fmtstr(char **sbuffer,
-       char **buffer,
-       size_t *currlen,
-       size_t *maxlen, const char *value, int flags, int min, int max)
-{
-    int padlen, strln;
-    int cnt = 0;
-
-    if (value == 0)
-        value = "<NULL>";
-    for (strln = 0; value[strln]; ++strln) ;
-    padlen = min - strln;
-    if (padlen < 0)
-        padlen = 0;
-    if (flags & DP_F_MINUS)
-        padlen = -padlen;
-
-    while ((padlen > 0) && (cnt < max)) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
-        --padlen;
-        ++cnt;
-    }
-    while (*value && (cnt < max)) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, *value++);
-        ++cnt;
-    }
-    while ((padlen < 0) && (cnt < max)) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
-        ++padlen;
-        ++cnt;
-    }
-}
-
-static void
-fmtint(char **sbuffer,
-       char **buffer,
-       size_t *currlen,
+    *truncated = (currlen > *maxlen - 1);
+    if (*truncated)
+        currlen = *maxlen - 1;
+    if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0'))
+        return 0;
+    *retlen = currlen - 1;
+    return 1;
+}
+
+static int
+fmtstr(char **sbuffer,
+       char **buffer,
+       size_t *currlen,
+       size_t *maxlen, const char *value, int flags, int min, int max)
+{
+    int padlen;
+    size_t strln;
+    int cnt = 0;
+
+    if (value == 0)
+        value = "<NULL>";
+
+    strln = strlen(value);
+    if (strln > INT_MAX)
+        strln = INT_MAX;
+
+    padlen = min - strln;
+    if (min < 0 || padlen < 0)
+        padlen = 0;
+    if (flags & DP_F_MINUS)
+        padlen = -padlen;
+
+    while ((padlen > 0) && (cnt < max)) {
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+            return 0;
+        --padlen;
+        ++cnt;
+    }
+    while (*value && (cnt < max)) {
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++))
+            return 0;
+        ++cnt;
+    }
+    while ((padlen < 0) && (cnt < max)) {
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+            return 0;
+        ++padlen;
+        ++cnt;
+    }
+    return 1;
+}
+
+static int
+fmtint(char **sbuffer,
+       char **buffer,
+       size_t *currlen,
        size_t *maxlen, LLONG value, int base, int min, int max, int flags)
 {
     int signvalue = 0;
@@ -514,43 +532,50 @@ fmtint(char **sbuffer,
     }
     if (flags & DP_F_MINUS)
         spadlen = -spadlen;
-
-    /* spaces */
-    while (spadlen > 0) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
-        --spadlen;
-    }
-
-    /* sign */
-    if (signvalue)
-        doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
-
-    /* prefix */
-    while (*prefix) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix);
-        prefix++;
-    }
-
-    /* zeros */
-    if (zpadlen > 0) {
-        while (zpadlen > 0) {
-            doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
-            --zpadlen;
-        }
-    }
-    /* digits */
-    while (place > 0)
-        doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]);
-
-    /* left justified spaces */
-    while (spadlen < 0) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
-        ++spadlen;
-    }
-    return;
-}
-
-static LDOUBLE abs_val(LDOUBLE value)
+
+    /* spaces */
+    while (spadlen > 0) {
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+            return 0;
+        --spadlen;
+    }
+
+    /* sign */
+    if (signvalue)
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+            return 0;
+
+    /* prefix */
+    while (*prefix) {
+        if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix))
+            return 0;
+        prefix++;
+    }
+
+    /* zeros */
+    if (zpadlen > 0) {
+        while (zpadlen > 0) {
+            if(!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+                return 0;
+            --zpadlen;
+        }
+    }
+    /* digits */
+    while (place > 0) {
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]))
+            return 0;
+    }
+
+    /* left justified spaces */
+    while (spadlen < 0) {
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+            return 0;
+        ++spadlen;
+    }
+    return 1;
+}
+
+static LDOUBLE abs_val(LDOUBLE value)
 {
     LDOUBLE result = value;
     if (value < 0)
@@ -575,13 +600,13 @@ static long roundv(LDOUBLE value)
     value = value - intpart;
     if (value >= 0.5)
         intpart++;
-    return intpart;
-}
-
-static void
-fmtfp(char **sbuffer,
-      char **buffer,
-      size_t *currlen,
+    return intpart;
+}
+
+static int
+fmtfp(char **sbuffer,
+      char **buffer,
+      size_t *currlen,
       size_t *maxlen, LDOUBLE fvalue, int min, int max, int flags)
 {
     int signvalue = 0;
@@ -657,87 +682,107 @@ fmtfp(char **sbuffer,
         padlen = 0;
     if (flags & DP_F_MINUS)
         padlen = -padlen;
-
-    if ((flags & DP_F_ZERO) && (padlen > 0)) {
-        if (signvalue) {
-            doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
-            --padlen;
-            signvalue = 0;
-        }
-        while (padlen > 0) {
-            doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
-            --padlen;
-        }
-    }
-    while (padlen > 0) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
-        --padlen;
-    }
-    if (signvalue)
-        doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
-
-    while (iplace > 0)
-        doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]);
-
-    /*
-     * Decimal point. This should probably use locale to find the correct
-     * char to print out.
-     */
-    if (max > 0 || (flags & DP_F_NUM)) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, '.');
-
-        while (fplace > 0)
-            doapr_outch(sbuffer, buffer, currlen, maxlen, fconvert[--fplace]);
-    }
-    while (zpadlen > 0) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
-        --zpadlen;
-    }
-
-    while (padlen < 0) {
-        doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
-        ++padlen;
-    }
-}
-
-static void
-doapr_outch(char **sbuffer,
-            char **buffer, size_t *currlen, size_t *maxlen, int c)
-{
-    /* If we haven't at least one buffer, someone has doe a big booboo */
-    assert(*sbuffer != NULL || buffer != NULL);
-
-    if (buffer) {
-        while (*currlen >= *maxlen) {
-            if (*buffer == NULL) {
-                if (*maxlen == 0)
-                    *maxlen = 1024;
-                *buffer = OPENSSL_malloc(*maxlen);
-                if (*currlen > 0) {
-                    assert(*sbuffer != NULL);
-                    memcpy(*buffer, *sbuffer, *currlen);
-                }
-                *sbuffer = NULL;
-            } else {
-                *maxlen += 1024;
-                *buffer = OPENSSL_realloc(*buffer, *maxlen);
-            }
-        }
-        /* What to do if *buffer is NULL? */
-        assert(*sbuffer != NULL || *buffer != NULL);
-    }
-
-    if (*currlen < *maxlen) {
-        if (*sbuffer)
+
+    if ((flags & DP_F_ZERO) && (padlen > 0)) {
+        if (signvalue) {
+            if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+                return 0;
+            --padlen;
+            signvalue = 0;
+        }
+        while (padlen > 0) {
+            if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+                return 0;
+            --padlen;
+        }
+    }
+    while (padlen > 0) {
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+            return 0;
+        --padlen;
+    }
+    if (signvalue && !doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue))
+        return 0;
+
+    while (iplace > 0) {
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]))
+            return 0;
+    }
+
+    /*
+     * Decimal point. This should probably use locale to find the correct
+     * char to print out.
+     */
+    if (max > 0 || (flags & DP_F_NUM)) {
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '.'))
+            return 0;
+
+        while (fplace > 0) {
+            if(!doapr_outch(sbuffer, buffer, currlen, maxlen,
+                            fconvert[--fplace]))
+                return 0;
+        }
+    }
+    while (zpadlen > 0) {
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0'))
+            return 0;
+        --zpadlen;
+    }
+
+    while (padlen < 0) {
+        if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' '))
+            return 0;
+        ++padlen;
+    }
+    return 1;
+}
+
+#define BUFFER_INC  1024
+
+static int
+doapr_outch(char **sbuffer,
+            char **buffer, size_t *currlen, size_t *maxlen, int c)
+{
+    /* If we haven't at least one buffer, someone has doe a big booboo */
+    assert(*sbuffer != NULL || buffer != NULL);
+
+    /* |currlen| must always be <= |*maxlen| */
+    assert(*currlen <= *maxlen);
+
+    if (buffer && *currlen == *maxlen) {
+        if (*maxlen > INT_MAX - BUFFER_INC)
+            return 0;
+
+        *maxlen += BUFFER_INC;
+            if (*buffer == NULL) {
+                *buffer = OPENSSL_malloc(*maxlen);
+                if (*buffer == NULL)
+                    return 0;
+                if (*currlen > 0) {
+                    assert(*sbuffer != NULL);
+                    memcpy(*buffer, *sbuffer, *currlen);
+                }
+                *sbuffer = NULL;
+            } else {
+                char *tmpbuf;
+                tmpbuf = OPENSSL_realloc(*buffer, *maxlen);
+                if (tmpbuf == NULL)
+                    return 0;
+                *buffer = tmpbuf;
+            }
+        }
+
+    if (*currlen < *maxlen) {
+        if (*sbuffer)
             (*sbuffer)[(*currlen)++] = (char)c;
         else
-            (*buffer)[(*currlen)++] = (char)c;
-    }
-
-    return;
-}
-
-/***************************************************************************/
+            (*buffer)[(*currlen)++] = (char)c;
+    }
+
+    return 1;
+}
+
+/***************************************************************************/
 
 int BIO_printf(BIO *bio, const char *format, ...)
 {
@@ -763,13 +808,17 @@ int BIO_vprintf(BIO *bio, const char *fo
     size_t hugebufsize = sizeof(hugebuf);
     char *dynbuf = NULL;
     int ignored;
-
-    dynbuf = NULL;
-    CRYPTO_push_info("doapr()");
-    _dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format, args);
-    if (dynbuf) {
-        ret = BIO_write(bio, dynbuf, (int)retlen);
-        OPENSSL_free(dynbuf);
+
+    dynbuf = NULL;
+    CRYPTO_push_info("doapr()");
+    if (!_dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format,
+                args)) {
+        OPENSSL_free(dynbuf);
+        return -1;
+    }
+    if (dynbuf) {
+        ret = BIO_write(bio, dynbuf, (int)retlen);
+        OPENSSL_free(dynbuf);
     } else {
         ret = BIO_write(bio, hugebuf, (int)retlen);
     }
@@ -798,13 +847,14 @@ int BIO_snprintf(char *buf, size_t n, co
 
 int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
 {
-    size_t retlen;
-    int truncated;
-
-    _dopr(&buf, NULL, &n, &retlen, &truncated, format, args);
-
-    if (truncated)
-        /*
+    size_t retlen;
+    int truncated;
+
+    if(!_dopr(&buf, NULL, &n, &retlen, &truncated, format, args))
+        return -1;
+
+    if (truncated)
+        /*
          * In case of truncation, return -1 like traditional snprintf.
          * (Current drafts for ISO/IEC 9899 say snprintf should return the
          * number of characters that would have been written, had the buffer

Modified: stable/9/crypto/openssl/crypto/bn/bn.h
==============================================================================
--- stable/9/crypto/openssl/crypto/bn/bn.h	Mon Mar  7 16:13:54 2016	(r296461)
+++ stable/9/crypto/openssl/crypto/bn/bn.h	Mon Mar  7 16:18:07 2016	(r296462)
@@ -69,12 +69,13 @@
  *
  */
 
-#ifndef HEADER_BN_H
-# define HEADER_BN_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>
 
@@ -701,14 +702,23 @@ const BIGNUM *BN_get0_nist_prime_224(voi
 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+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
 

Modified: stable/9/crypto/openssl/crypto/bn/bn_exp.c
==============================================================================
--- stable/9/crypto/openssl/crypto/bn/bn_exp.c	Mon Mar  7 16:13:54 2016	(r296461)
+++ stable/9/crypto/openssl/crypto/bn/bn_exp.c	Mon Mar  7 16:18:07 2016	(r296462)
@@ -107,12 +107,13 @@
  * (eay@cryptsoft.com).  This product includes software written by Tim
  * Hudson (tjh@cryptsoft.com).
  *
- */
-
-#include "cryptlib.h"
-#include "bn_lcl.h"
-
-/* maximum precomputation table size for *variable* sliding windows */
+ */
+
+#include "cryptlib.h"
+#include "constant_time_locl.h"
+#include "bn_lcl.h"
+
+/* maximum precomputation table size for *variable* sliding windows */
 #define TABLE_SIZE      32
 
 /* this one works - simple but works */
@@ -520,41 +521,79 @@ int BN_mod_exp_mont(BIGNUM *rr, const BI
  * 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 width)
-{
-    size_t i, j;
-
-    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 window)
+{
+    int i, j;
+    int width = 1 << window;
+    BN_ULONG *table = (BN_ULONG *)buf;
+
+    if (bn_wexpand(b, top) == NULL)
+        return 0;
     while (b->top < top) {
-        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);
+        b->d[b->top++] = 0;
+    }
+
+    for (i = 0, j = idx; i < top; i++, j += width) {
+        table[j] = 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 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;
+
+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;
     bn_correct_top(b);
     return 1;
 }
@@ -645,13 +684,13 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr
     /*
      * 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, numPowers))
-        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, window))
+        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)
@@ -664,13 +703,13 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr
     } 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, numPowers))
-        goto err;
-
-    /*
+        goto err;
+    if (!BN_copy(computeTemp, am))
+        goto err;
+    if (!MOD_EXP_CTIME_COPY_TO_PREBUF(am, top, powerbuf, 1, window))
+        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
@@ -679,14 +718,14 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr
     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, numPowers))
-                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,
+                                              window))
+                goto err;
+        }
+    }
 
     /*
      * Adjust the number of bits up to a multiple of the window size. If the

Modified: stable/9/crypto/openssl/crypto/bn/bn_print.c
==============================================================================
--- stable/9/crypto/openssl/crypto/bn/bn_print.c	Mon Mar  7 16:13:54 2016	(r296461)
+++ stable/9/crypto/openssl/crypto/bn/bn_print.c	Mon Mar  7 16:18:07 2016	(r296462)
@@ -55,12 +55,13 @@
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
-
-#include <stdio.h>
-#include <ctype.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";
 
@@ -186,14 +187,18 @@ int BN_hex2bn(BIGNUM **bn, const char *a
 
     if (*a == '-') {
         neg = 1;
-        a++;
-    }
-
-    for (i = 0; isxdigit((unsigned char)a[i]); i++) ;
-
-    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) {
@@ -201,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 digests; */
-    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;
@@ -257,14 +262,18 @@ int BN_dec2bn(BIGNUM **bn, const char *a

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201603071618.u27GI736079901>