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>