[Midnightbsd-cvs] src [6897] trunk/crypto/openssl: merge OpenSSL 0.9.8zc

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Tue Oct 28 07:53:51 EDT 2014


Revision: 6897
          http://svnweb.midnightbsd.org/src/?rev=6897
Author:   laffer1
Date:     2014-10-28 07:53:50 -0400 (Tue, 28 Oct 2014)
Log Message:
-----------
merge OpenSSL 0.9.8zc

Modified Paths:
--------------
    trunk/crypto/openssl/CHANGES
    trunk/crypto/openssl/Makefile
    trunk/crypto/openssl/NEWS
    trunk/crypto/openssl/README
    trunk/crypto/openssl/apps/s_client.c
    trunk/crypto/openssl/crypto/LPdir_vms.c
    trunk/crypto/openssl/crypto/LPdir_win.c
    trunk/crypto/openssl/crypto/Makefile
    trunk/crypto/openssl/crypto/bn/asm/x86_64-gcc.c
    trunk/crypto/openssl/crypto/bn/bn_exp.c
    trunk/crypto/openssl/crypto/bn/exptest.c
    trunk/crypto/openssl/crypto/ec/ec_key.c
    trunk/crypto/openssl/crypto/ec/ecp_smpl.c
    trunk/crypto/openssl/crypto/err/openssl.ec
    trunk/crypto/openssl/crypto/evp/Makefile
    trunk/crypto/openssl/crypto/evp/evp_enc.c
    trunk/crypto/openssl/crypto/opensslv.h
    trunk/crypto/openssl/crypto/rsa/Makefile
    trunk/crypto/openssl/crypto/rsa/rsa.h
    trunk/crypto/openssl/crypto/rsa/rsa_err.c
    trunk/crypto/openssl/crypto/rsa/rsa_oaep.c
    trunk/crypto/openssl/crypto/rsa/rsa_pk1.c
    trunk/crypto/openssl/crypto/rsa/rsa_sign.c
    trunk/crypto/openssl/doc/apps/s_client.pod
    trunk/crypto/openssl/doc/ssl/SSL_CTX_set_mode.pod
    trunk/crypto/openssl/e_os.h
    trunk/crypto/openssl/openssl.spec
    trunk/crypto/openssl/ssl/Makefile
    trunk/crypto/openssl/ssl/d1_lib.c
    trunk/crypto/openssl/ssl/dtls1.h
    trunk/crypto/openssl/ssl/s23_clnt.c
    trunk/crypto/openssl/ssl/s23_srvr.c
    trunk/crypto/openssl/ssl/s2_lib.c
    trunk/crypto/openssl/ssl/s3_cbc.c
    trunk/crypto/openssl/ssl/s3_clnt.c
    trunk/crypto/openssl/ssl/s3_enc.c
    trunk/crypto/openssl/ssl/s3_lib.c
    trunk/crypto/openssl/ssl/s3_pkt.c
    trunk/crypto/openssl/ssl/s3_srvr.c
    trunk/crypto/openssl/ssl/ssl.h
    trunk/crypto/openssl/ssl/ssl3.h
    trunk/crypto/openssl/ssl/ssl_err.c
    trunk/crypto/openssl/ssl/ssl_lib.c
    trunk/crypto/openssl/ssl/t1_enc.c
    trunk/crypto/openssl/ssl/t1_lib.c
    trunk/crypto/openssl/ssl/tls1.h
    trunk/crypto/openssl/test/Makefile

Added Paths:
-----------
    trunk/crypto/openssl/crypto/constant_time_locl.h
    trunk/crypto/openssl/crypto/constant_time_test.c
    trunk/crypto/openssl/test/constant_time_test.c

Property Changed:
----------------
    trunk/crypto/openssl/

Index: trunk/crypto/openssl
===================================================================
--- trunk/crypto/openssl	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl	2014-10-28 11:53:50 UTC (rev 6897)

Property changes on: trunk/crypto/openssl
___________________________________________________________________
Added: svn:mergeinfo
## -0,0 +1 ##
+/vendor-crypto/openssl/dist:6869-6896
\ No newline at end of property
Modified: trunk/crypto/openssl/CHANGES
===================================================================
--- trunk/crypto/openssl/CHANGES	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/CHANGES	2014-10-28 11:53:50 UTC (rev 6897)
@@ -2,6 +2,43 @@
  OpenSSL CHANGES
  _______________
 
+ Changes between 0.9.8zb and 0.9.8zc [15 Oct 2014]
+
+  *) Session Ticket Memory Leak.
+
+     When an OpenSSL SSL/TLS/DTLS server receives a session ticket the
+     integrity of that ticket is first verified. In the event of a session
+     ticket integrity check failing, OpenSSL will fail to free memory
+     causing a memory leak. By sending a large number of invalid session
+     tickets an attacker could exploit this issue in a Denial Of Service
+     attack.
+     (CVE-2014-3567)
+     [Steve Henson]
+
+  *) Build option no-ssl3 is incomplete.
+
+     When OpenSSL is configured with "no-ssl3" as a build option, servers
+     could accept and complete a SSL 3.0 handshake, and clients could be
+     configured to send them.
+     (CVE-2014-3568)
+     [Akamai and the OpenSSL team]
+
+  *) Add support for TLS_FALLBACK_SCSV.
+     Client applications doing fallback retries should call
+     SSL_set_mode(s, SSL_MODE_SEND_FALLBACK_SCSV).
+     (CVE-2014-3566)
+     [Adam Langley, Bodo Moeller]
+
+  *) Add additional DigestInfo checks.
+ 
+     Reencode DigestInto in DER and check against the original when
+     verifying RSA signature: this will reject any improperly encoded
+     DigestInfo structures.
+
+     Note: this is a precautionary measure and no attacks are currently known.
+
+     [Steve Henson]
+
  Changes between 0.9.8za and 0.9.8zb [6 Aug 2014]
 
   *) OpenSSL DTLS clients enabling anonymous (EC)DH ciphersuites are subject

Modified: trunk/crypto/openssl/Makefile
===================================================================
--- trunk/crypto/openssl/Makefile	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/Makefile	2014-10-28 11:53:50 UTC (rev 6897)
@@ -4,7 +4,7 @@
 ## Makefile for OpenSSL
 ##
 
-VERSION=0.9.8zb
+VERSION=0.9.8zc
 MAJOR=0
 MINOR=9.8
 SHLIB_VERSION_NUMBER=0.9.8

Modified: trunk/crypto/openssl/NEWS
===================================================================
--- trunk/crypto/openssl/NEWS	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/NEWS	2014-10-28 11:53:50 UTC (rev 6897)
@@ -5,6 +5,13 @@
   This file gives a brief overview of the major changes between each OpenSSL
   release. For more details please read the CHANGES file.
 
+  Major changes between OpenSSL 0.9.8zb and OpenSSL 0.9.8zc [15 Oct 2014]:
+
+      o Fix for CVE-2014-3513
+      o Fix for CVE-2014-3567
+      o Mitigation for CVE-2014-3566 (SSL protocol vulnerability)
+      o Fix for CVE-2014-3568
+
   Major changes between OpenSSL 0.9.8za and OpenSSL 0.9.8zb [6 Aug 2014]:
 
       o Fix for CVE-2014-3510

Modified: trunk/crypto/openssl/README
===================================================================
--- trunk/crypto/openssl/README	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/README	2014-10-28 11:53:50 UTC (rev 6897)
@@ -1,5 +1,5 @@
 
- OpenSSL 0.9.8zb 6 Aug 2014
+ OpenSSL 0.9.8zc 15 Oct 2014
 
  Copyright (c) 1998-2011 The OpenSSL Project
  Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson

Modified: trunk/crypto/openssl/apps/s_client.c
===================================================================
--- trunk/crypto/openssl/apps/s_client.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/apps/s_client.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -226,6 +226,7 @@
 	BIO_printf(bio_err," -ssl3         - just use SSLv3\n");
 	BIO_printf(bio_err," -tls1         - just use TLSv1\n");
 	BIO_printf(bio_err," -dtls1        - just use DTLSv1\n");    
+	BIO_printf(bio_err," -fallback_scsv - send TLS_FALLBACK_SCSV\n");
 	BIO_printf(bio_err," -mtu          - set the link layer MTU\n");
 	BIO_printf(bio_err," -no_tls1/-no_ssl3/-no_ssl2 - turn off that protocol\n");
 	BIO_printf(bio_err," -bugs         - Switch on all SSL implementation bug workarounds\n");
@@ -339,6 +340,7 @@
 	char *sess_out = NULL;
 	struct sockaddr peer;
 	int peerlen = sizeof(peer);
+	int fallback_scsv = 0;
 	int enable_timeouts = 0 ;
 	long socket_mtu = 0;
 #ifndef OPENSSL_NO_JPAKE
@@ -488,6 +490,10 @@
 			socket_mtu = atol(*(++argv));
 			}
 #endif
+		else if (strcmp(*argv,"-fallback_scsv") == 0)
+			{
+			fallback_scsv = 1;
+			}
 		else if (strcmp(*argv,"-bugs") == 0)
 			bugs=1;
 		else if	(strcmp(*argv,"-keyform") == 0)
@@ -778,6 +784,10 @@
 		SSL_set_session(con, sess);
 		SSL_SESSION_free(sess);
 		}
+
+	if (fallback_scsv)
+		SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV);
+
 #ifndef OPENSSL_NO_TLSEXT
 	if (servername != NULL)
 		{

Modified: trunk/crypto/openssl/crypto/LPdir_vms.c
===================================================================
--- trunk/crypto/openssl/crypto/LPdir_vms.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/crypto/LPdir_vms.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -1,4 +1,3 @@
-/* $LP: LPlib/source/LPdir_vms.c,v 1.20 2004/08/26 13:36:05 _cvs_levitte Exp $ */
 /*
  * Copyright (c) 2004, Richard Levitte <richard at levitte.org>
  * All rights reserved.
@@ -82,6 +81,12 @@
       size_t filespeclen = strlen(directory);
       char *filespec = NULL;
 
+      if (filespeclen == 0)
+	{
+	  errno = ENOENT;
+	  return 0;
+	}
+
       /* MUST be a VMS directory specification!  Let's estimate if it is. */
       if (directory[filespeclen-1] != ']'
 	  && directory[filespeclen-1] != '>'

Modified: trunk/crypto/openssl/crypto/LPdir_win.c
===================================================================
--- trunk/crypto/openssl/crypto/LPdir_win.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/crypto/LPdir_win.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -1,4 +1,3 @@
-/* $LP: LPlib/source/LPdir_win.c,v 1.10 2004/08/26 13:36:05 _cvs_levitte Exp $ */
 /*
  * Copyright (c) 2004, Richard Levitte <richard at levitte.org>
  * All rights reserved.
@@ -65,6 +64,16 @@
   errno = 0;
   if (*ctx == NULL)
     {
+      const char *extdir = directory;
+      char *extdirbuf = NULL;
+      size_t dirlen = strlen (directory);
+
+      if (dirlen == 0)
+	{
+	  errno = ENOENT;
+	  return 0;
+	}
+
       *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX));
       if (*ctx == NULL)
 	{
@@ -73,15 +82,35 @@
 	}
       memset(*ctx, '\0', sizeof(LP_DIR_CTX));
 
+      if (directory[dirlen-1] != '*')
+	{
+	  extdirbuf = (char *)malloc(dirlen + 3);
+	  if (extdirbuf == NULL)
+	    {
+	      free(*ctx);
+	      *ctx = NULL;
+	      errno = ENOMEM;
+	      return 0;
+	    }
+	  if (directory[dirlen-1] != '/' && directory[dirlen-1] != '\\')
+	    extdir = strcat(strcpy (extdirbuf,directory),"/*");
+	  else
+	    extdir = strcat(strcpy (extdirbuf,directory),"*");
+	}
+
       if (sizeof(TCHAR) != sizeof(char))
 	{
 	  TCHAR *wdir = NULL;
 	  /* len_0 denotes string length *with* trailing 0 */ 
-	  size_t index = 0,len_0 = strlen(directory) + 1;
+	  size_t index = 0,len_0 = strlen(extdir) + 1;
 
-	  wdir = (TCHAR *)malloc(len_0 * sizeof(TCHAR));
+	  wdir = (TCHAR *)calloc(len_0, sizeof(TCHAR));
 	  if (wdir == NULL)
 	    {
+	      if (extdirbuf != NULL)
+		{
+		  free (extdirbuf);
+		}
 	      free(*ctx);
 	      *ctx = NULL;
 	      errno = ENOMEM;
@@ -89,10 +118,10 @@
 	    }
 
 #ifdef LP_MULTIBYTE_AVAILABLE
-	  if (!MultiByteToWideChar(CP_ACP, 0, directory, len_0, (WCHAR *)wdir, len_0))
+	  if (!MultiByteToWideChar(CP_ACP, 0, extdir, len_0, (WCHAR *)wdir, len_0))
 #endif
 	    for (index = 0; index < len_0; index++)
-	      wdir[index] = (TCHAR)directory[index];
+	      wdir[index] = (TCHAR)extdir[index];
 
 	  (*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx);
 
@@ -99,7 +128,13 @@
 	  free(wdir);
 	}
       else
-	(*ctx)->handle = FindFirstFile((TCHAR *)directory, &(*ctx)->ctx);
+	{
+	  (*ctx)->handle = FindFirstFile((TCHAR *)extdir, &(*ctx)->ctx);
+	}
+      if (extdirbuf != NULL)
+	{
+	  free (extdirbuf);
+	}
 
       if ((*ctx)->handle == INVALID_HANDLE_VALUE)
 	{
@@ -116,7 +151,6 @@
 	  return 0;
 	}
     }
-
   if (sizeof(TCHAR) != sizeof(char))
     {
       TCHAR *wdir = (*ctx)->ctx.cFileName;

Modified: trunk/crypto/openssl/crypto/Makefile
===================================================================
--- trunk/crypto/openssl/crypto/Makefile	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/crypto/Makefile	2014-10-28 11:53:50 UTC (rev 6897)
@@ -30,6 +30,7 @@
 LIBS=
 
 GENERAL=Makefile README crypto-lib.com install.com
+TEST=constant_time_test.c
 
 LIB= $(TOP)/libcrypto.a
 SHARED_LIB= libcrypto$(SHLIB_EXT)

Modified: trunk/crypto/openssl/crypto/bn/asm/x86_64-gcc.c
===================================================================
--- trunk/crypto/openssl/crypto/bn/asm/x86_64-gcc.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/crypto/bn/asm/x86_64-gcc.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -185,7 +185,7 @@
 
 	if (n <= 0) return 0;
 
-	asm (
+	asm volatile (
 	"	subq	%2,%2		\n"
 	".align 16			\n"
 	"1:	movq	(%4,%2,8),%0	\n"
@@ -196,7 +196,7 @@
 	"	sbbq	%0,%0		\n"
 		: "=&a"(ret),"+c"(n),"=&r"(i)
 		: "r"(rp),"r"(ap),"r"(bp)
-		: "cc"
+		: "cc", "memory"
 	);
 
   return ret&1;
@@ -208,7 +208,7 @@
 
 	if (n <= 0) return 0;
 
-	asm (
+	asm volatile (
 	"	subq	%2,%2		\n"
 	".align 16			\n"
 	"1:	movq	(%4,%2,8),%0	\n"
@@ -219,7 +219,7 @@
 	"	sbbq	%0,%0		\n"
 		: "=&a"(ret),"+c"(n),"=&r"(i)
 		: "r"(rp),"r"(ap),"r"(bp)
-		: "cc"
+		: "cc", "memory"
 	);
 
   return ret&1;

Modified: trunk/crypto/openssl/crypto/bn/bn_exp.c
===================================================================
--- trunk/crypto/openssl/crypto/bn/bn_exp.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/crypto/bn/bn_exp.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -767,7 +767,14 @@
 	bits = BN_num_bits(p);
 	if (bits == 0)
 		{
-		ret = BN_one(rr);
+		/* x**0 mod 1 is still zero. */
+		if (BN_is_one(m))
+			{
+			ret = 1;
+			BN_zero(rr);
+			}
+		else
+			ret = BN_one(rr);
 		return ret;
 		}
 	if (a == 0)

Modified: trunk/crypto/openssl/crypto/bn/exptest.c
===================================================================
--- trunk/crypto/openssl/crypto/bn/exptest.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/crypto/bn/exptest.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -71,6 +71,43 @@
 
 static const char rnd_seed[] = "string to make the random number generator think it has entropy";
 
+/* test_exp_mod_zero tests that x**0 mod 1 == 0. It returns zero on success. */
+static int test_exp_mod_zero() {
+	BIGNUM a, p, m;
+	BIGNUM r;
+	BN_CTX *ctx = BN_CTX_new();
+	int ret = 1;
+
+	BN_init(&m);
+	BN_one(&m);
+
+	BN_init(&a);
+	BN_one(&a);
+
+	BN_init(&p);
+	BN_zero(&p);
+
+	BN_init(&r);
+	BN_mod_exp(&r, &a, &p, &m, ctx);
+	BN_CTX_free(ctx);
+
+	if (BN_is_zero(&r))
+		ret = 0;
+	else
+		{
+		printf("1**0 mod 1 = ");
+		BN_print_fp(stdout, &r);
+		printf(", should be 0\n");
+		}
+
+	BN_free(&r);
+	BN_free(&a);
+	BN_free(&p);
+	BN_free(&m);
+
+	return ret;
+}
+
 int main(int argc, char *argv[])
 	{
 	BN_CTX *ctx;
@@ -190,7 +227,13 @@
 	ERR_remove_state(0);
 	CRYPTO_mem_leaks(out);
 	BIO_free(out);
-	printf(" done\n");
+	printf("\n");
+
+	if (test_exp_mod_zero() != 0)
+		goto err;
+
+	printf("done\n");
+
 	EXIT(0);
 err:
 	ERR_load_crypto_strings();

Copied: trunk/crypto/openssl/crypto/constant_time_locl.h (from rev 6896, vendor-crypto/openssl/dist/crypto/constant_time_locl.h)
===================================================================
--- trunk/crypto/openssl/crypto/constant_time_locl.h	                        (rev 0)
+++ trunk/crypto/openssl/crypto/constant_time_locl.h	2014-10-28 11:53:50 UTC (rev 6897)
@@ -0,0 +1,216 @@
+/* crypto/constant_time_locl.h */
+/*
+ * Utilities for constant-time cryptography.
+ *
+ * Author: Emilia Kasper (emilia at openssl.org)
+ * Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley
+ * (Google).
+ * ====================================================================
+ * Copyright (c) 2014 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay at cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh at cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_CONSTANT_TIME_LOCL_H
+#define HEADER_CONSTANT_TIME_LOCL_H
+
+#include "e_os.h"  /* For 'inline' */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The boolean methods return a bitmask of all ones (0xff...f) for true
+ * and 0 for false. This is useful for choosing a value based on the result
+ * of a conditional in constant time. For example,
+ *
+ * if (a < b) {
+ *   c = a;
+ * } else {
+ *   c = b;
+ * }
+ *
+ * can be written as
+ *
+ * unsigned int lt = constant_time_lt(a, b);
+ * c = constant_time_select(lt, a, b);
+ */
+
+/*
+ * Returns the given value with the MSB copied to all the other
+ * bits. Uses the fact that arithmetic shift shifts-in the sign bit.
+ * However, this is not ensured by the C standard so you may need to
+ * replace this with something else on odd CPUs.
+ */
+static inline unsigned int constant_time_msb(unsigned int a);
+
+/*
+ * Returns 0xff..f if a < b and 0 otherwise.
+ */
+static inline unsigned int constant_time_lt(unsigned int a, unsigned int b);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b);
+
+/*
+ * Returns 0xff..f if a >= b and 0 otherwise.
+ */
+static inline unsigned int constant_time_ge(unsigned int a, unsigned int b);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b);
+
+/*
+ * Returns 0xff..f if a == 0 and 0 otherwise.
+ */
+static inline unsigned int constant_time_is_zero(unsigned int a);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_is_zero_8(unsigned int a);
+
+
+/*
+ * Returns 0xff..f if a == b and 0 otherwise.
+ */
+static inline unsigned int constant_time_eq(unsigned int a, unsigned int b);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b);
+/* Signed integers. */
+static inline unsigned int constant_time_eq_int(int a, int b);
+/* Convenience method for getting an 8-bit mask. */
+static inline unsigned char constant_time_eq_int_8(int a, int b);
+
+
+/*
+ * Returns (mask & a) | (~mask & b).
+ *
+ * When |mask| is all 1s or all 0s (as returned by the methods above),
+ * the select methods return either |a| (if |mask| is nonzero) or |b|
+ * (if |mask| is zero).
+ */
+static inline unsigned int constant_time_select(unsigned int mask,
+	unsigned int a, unsigned int b);
+/* Convenience method for unsigned chars. */
+static inline unsigned char constant_time_select_8(unsigned char mask,
+	unsigned char a, unsigned char b);
+/* Convenience method for signed integers. */
+static inline int constant_time_select_int(unsigned int mask, int a, int b);
+
+static inline unsigned int constant_time_msb(unsigned int a)
+	{
+	return (unsigned int)((int)(a) >> (sizeof(int) * 8 - 1));
+	}
+
+static inline unsigned int constant_time_lt(unsigned int a, unsigned int b)
+	{
+	unsigned int lt;
+	/* Case 1: msb(a) == msb(b). a < b iff the MSB of a - b is set.*/
+	lt = ~(a ^ b) & (a - b);
+	/* Case 2: msb(a) != msb(b). a < b iff the MSB of b is set. */
+	lt |= ~a & b;
+	return constant_time_msb(lt);
+	}
+
+static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b)
+	{
+	return (unsigned char)(constant_time_lt(a, b));
+	}
+
+static inline unsigned int constant_time_ge(unsigned int a, unsigned int b)
+	{
+	unsigned int ge;
+	/* Case 1: msb(a) == msb(b). a >= b iff the MSB of a - b is not set.*/
+	ge = ~((a ^ b) | (a - b));
+	/* Case 2: msb(a) != msb(b). a >= b iff the MSB of a is set. */
+	ge |= a & ~b;
+	return constant_time_msb(ge);
+	}
+
+static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b)
+	{
+	return (unsigned char)(constant_time_ge(a, b));
+	}
+
+static inline unsigned int constant_time_is_zero(unsigned int a)
+	{
+	return constant_time_msb(~a & (a - 1));
+	}
+
+static inline unsigned char constant_time_is_zero_8(unsigned int a)
+	{
+	return (unsigned char)(constant_time_is_zero(a));
+	}
+
+static inline unsigned int constant_time_eq(unsigned int a, unsigned int b)
+	{
+	return constant_time_is_zero(a ^ b);
+	}
+
+static inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b)
+	{
+	return (unsigned char)(constant_time_eq(a, b));
+	}
+
+static inline unsigned int constant_time_eq_int(int a, int b)
+	{
+	return constant_time_eq((unsigned)(a), (unsigned)(b));
+	}
+
+static inline unsigned char constant_time_eq_int_8(int a, int b)
+	{
+	return constant_time_eq_8((unsigned)(a), (unsigned)(b));
+	}
+
+static inline unsigned int constant_time_select(unsigned int mask,
+	unsigned int a, unsigned int b)
+	{
+	return (mask & a) | (~mask & b);
+	}
+
+static inline unsigned char constant_time_select_8(unsigned char mask,
+	unsigned char a, unsigned char b)
+	{
+	return (unsigned char)(constant_time_select(mask, a, b));
+	}
+
+inline int constant_time_select_int(unsigned int mask, int a, int b)
+	{
+	return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b)));
+	}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* HEADER_CONSTANT_TIME_LOCL_H */

Copied: trunk/crypto/openssl/crypto/constant_time_test.c (from rev 6896, vendor-crypto/openssl/dist/crypto/constant_time_test.c)
===================================================================
--- trunk/crypto/openssl/crypto/constant_time_test.c	                        (rev 0)
+++ trunk/crypto/openssl/crypto/constant_time_test.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -0,0 +1,330 @@
+/* crypto/constant_time_test.c */
+/*
+ * Utilities for constant-time cryptography.
+ *
+ * Author: Emilia Kasper (emilia at openssl.org)
+ * Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley
+ * (Google).
+ * ====================================================================
+ * Copyright (c) 2014 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay at cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh at cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "../crypto/constant_time_locl.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static const unsigned int CONSTTIME_TRUE = (unsigned)(~0);
+static const unsigned int CONSTTIME_FALSE = 0;
+static const unsigned char CONSTTIME_TRUE_8 = 0xff;
+static const unsigned char CONSTTIME_FALSE_8 = 0;
+
+static int test_binary_op(unsigned int (*op)(unsigned int a, unsigned int b),
+	const char* op_name, unsigned int a, unsigned int b, int is_true)
+	{
+	unsigned c = op(a, b);
+	if (is_true && c != CONSTTIME_TRUE)
+		{
+		fprintf(stderr, "Test failed for %s(%du, %du): expected %du "
+			"(TRUE), got %du\n", op_name, a, b, CONSTTIME_TRUE, c);
+		return 1;
+		}
+	else if (!is_true && c != CONSTTIME_FALSE)
+		{
+		fprintf(stderr, "Test failed for  %s(%du, %du): expected %du "
+			"(FALSE), got %du\n", op_name, a, b, CONSTTIME_FALSE,
+			c);
+		return 1;
+		}
+        return 0;
+	}
+
+static int test_binary_op_8(unsigned char (*op)(unsigned int a, unsigned int b),
+	const char* op_name, unsigned int a, unsigned int b, int is_true)
+	{
+	unsigned char c = op(a, b);
+	if (is_true && c != CONSTTIME_TRUE_8)
+		{
+		fprintf(stderr, "Test failed for %s(%du, %du): expected %u "
+			"(TRUE), got %u\n", op_name, a, b, CONSTTIME_TRUE_8, c);
+		return 1;
+		}
+	else if (!is_true && c != CONSTTIME_FALSE_8)
+		{
+		fprintf(stderr, "Test failed for  %s(%du, %du): expected %u "
+			"(FALSE), got %u\n", op_name, a, b, CONSTTIME_FALSE_8,
+			c);
+		return 1;
+		}
+        return 0;
+	}
+
+static int test_is_zero(unsigned int a)
+	{
+	unsigned int c = constant_time_is_zero(a);
+	if (a == 0 && c != CONSTTIME_TRUE)
+		{
+		fprintf(stderr, "Test failed for constant_time_is_zero(%du): "
+			"expected %du (TRUE), got %du\n", a, CONSTTIME_TRUE, c);
+		return 1;
+		}
+	else if (a != 0 && c != CONSTTIME_FALSE)
+		{
+		fprintf(stderr, "Test failed for constant_time_is_zero(%du): "
+			"expected %du (FALSE), got %du\n", a, CONSTTIME_FALSE,
+			c);
+		return 1;
+		}
+        return 0;
+	}
+
+static int test_is_zero_8(unsigned int a)
+	{
+	unsigned char c = constant_time_is_zero_8(a);
+	if (a == 0 && c != CONSTTIME_TRUE_8)
+		{
+		fprintf(stderr, "Test failed for constant_time_is_zero(%du): "
+			"expected %u (TRUE), got %u\n", a, CONSTTIME_TRUE_8, c);
+		return 1;
+		}
+	else if (a != 0 && c != CONSTTIME_FALSE)
+		{
+		fprintf(stderr, "Test failed for constant_time_is_zero(%du): "
+			"expected %u (FALSE), got %u\n", a, CONSTTIME_FALSE_8,
+			c);
+		return 1;
+		}
+        return 0;
+	}
+
+static int test_select(unsigned int a, unsigned int b)
+	{
+	unsigned int selected = constant_time_select(CONSTTIME_TRUE, a, b);
+	if (selected != a)
+		{
+		fprintf(stderr, "Test failed for constant_time_select(%du, %du,"
+			"%du): expected %du(first value), got %du\n",
+			CONSTTIME_TRUE, a, b, a, selected);
+		return 1;
+		}
+	selected = constant_time_select(CONSTTIME_FALSE, a, b);
+	if (selected != b)
+		{
+		fprintf(stderr, "Test failed for constant_time_select(%du, %du,"
+			"%du): expected %du(second value), got %du\n",
+			CONSTTIME_FALSE, a, b, b, selected);
+		return 1;
+		}
+	return 0;
+	}
+
+static int test_select_8(unsigned char a, unsigned char b)
+	{
+	unsigned char selected = constant_time_select_8(CONSTTIME_TRUE_8, a, b);
+	if (selected != a)
+		{
+		fprintf(stderr, "Test failed for constant_time_select(%u, %u,"
+			"%u): expected %u(first value), got %u\n",
+			CONSTTIME_TRUE, a, b, a, selected);
+		return 1;
+		}
+	selected = constant_time_select_8(CONSTTIME_FALSE_8, a, b);
+	if (selected != b)
+		{
+		fprintf(stderr, "Test failed for constant_time_select(%u, %u,"
+			"%u): expected %u(second value), got %u\n",
+			CONSTTIME_FALSE, a, b, b, selected);
+		return 1;
+		}
+	return 0;
+	}
+
+static int test_select_int(int a, int b)
+	{
+	int selected = constant_time_select_int(CONSTTIME_TRUE, a, b);
+	if (selected != a)
+		{
+		fprintf(stderr, "Test failed for constant_time_select(%du, %d,"
+			"%d): expected %d(first value), got %d\n",
+			CONSTTIME_TRUE, a, b, a, selected);
+		return 1;
+		}
+	selected = constant_time_select_int(CONSTTIME_FALSE, a, b);
+	if (selected != b)
+		{
+		fprintf(stderr, "Test failed for constant_time_select(%du, %d,"
+			"%d): expected %d(second value), got %d\n",
+			CONSTTIME_FALSE, a, b, b, selected);
+		return 1;
+		}
+	return 0;
+	}
+
+static int test_eq_int(int a, int b)
+	{
+	unsigned int equal = constant_time_eq_int(a, b);
+	if (a == b && equal != CONSTTIME_TRUE)
+		{
+		fprintf(stderr, "Test failed for constant_time_eq_int(%d, %d): "
+			"expected %du(TRUE), got %du\n",
+			a, b, CONSTTIME_TRUE, equal);
+		return 1;
+		}
+	else if (a != b && equal != CONSTTIME_FALSE)
+		{
+		fprintf(stderr, "Test failed for constant_time_eq_int(%d, %d): "
+			"expected %du(FALSE), got %du\n",
+			a, b, CONSTTIME_FALSE, equal);
+		return 1;
+		}
+	return 0;
+	}
+
+static int test_eq_int_8(int a, int b)
+	{
+	unsigned char equal = constant_time_eq_int_8(a, b);
+	if (a == b && equal != CONSTTIME_TRUE_8)
+		{
+		fprintf(stderr, "Test failed for constant_time_eq_int_8(%d, %d): "
+			"expected %u(TRUE), got %u\n",
+			a, b, CONSTTIME_TRUE_8, equal);
+		return 1;
+		}
+	else if (a != b && equal != CONSTTIME_FALSE_8)
+		{
+		fprintf(stderr, "Test failed for constant_time_eq_int_8(%d, %d): "
+			"expected %u(FALSE), got %u\n",
+			a, b, CONSTTIME_FALSE_8, equal);
+		return 1;
+		}
+	return 0;
+	}
+
+static unsigned int test_values[] = {0, 1, 1024, 12345, 32000, UINT_MAX/2-1,
+                                     UINT_MAX/2, UINT_MAX/2+1, UINT_MAX-1,
+                                     UINT_MAX};
+
+static unsigned char test_values_8[] = {0, 1, 2, 20, 32, 127, 128, 129, 255};
+
+static int signed_test_values[] = {0, 1, -1, 1024, -1024, 12345, -12345,
+				   32000, -32000, INT_MAX, INT_MIN, INT_MAX-1,
+				   INT_MIN+1};
+
+
+int main(int argc, char *argv[])
+	{
+	unsigned int a, b, i, j;
+	int c, d;
+	unsigned char e, f;
+	int num_failed = 0, num_all = 0;
+	fprintf(stdout, "Testing constant time operations...\n");
+
+	for (i = 0; i < sizeof(test_values)/sizeof(int); ++i)
+		{
+		a = test_values[i];
+		num_failed += test_is_zero(a);
+		num_failed += test_is_zero_8(a);
+		num_all += 2;
+		for (j = 0; j < sizeof(test_values)/sizeof(int); ++j)
+			{
+			b = test_values[j];
+			num_failed += test_binary_op(&constant_time_lt,
+				"constant_time_lt", a, b, a < b);
+			num_failed += test_binary_op_8(&constant_time_lt_8,
+				"constant_time_lt_8", a, b, a < b);
+			num_failed += test_binary_op(&constant_time_lt,
+				"constant_time_lt_8", b, a, b < a);
+			num_failed += test_binary_op_8(&constant_time_lt_8,
+				"constant_time_lt_8", b, a, b < a);
+			num_failed += test_binary_op(&constant_time_ge,
+				"constant_time_ge", a, b, a >= b);
+			num_failed += test_binary_op_8(&constant_time_ge_8,
+				"constant_time_ge_8", a, b, a >= b);
+			num_failed += test_binary_op(&constant_time_ge,
+				"constant_time_ge", b, a, b >= a);
+			num_failed += test_binary_op_8(&constant_time_ge_8,
+				"constant_time_ge_8", b, a, b >= a);
+			num_failed += test_binary_op(&constant_time_eq,
+				"constant_time_eq", a, b, a == b);
+			num_failed += test_binary_op_8(&constant_time_eq_8,
+				"constant_time_eq_8", a, b, a == b);
+			num_failed += test_binary_op(&constant_time_eq,
+				"constant_time_eq", b, a, b == a);
+			num_failed += test_binary_op_8(&constant_time_eq_8,
+				"constant_time_eq_8", b, a, b == a);
+			num_failed += test_select(a, b);
+			num_all += 13;
+			}
+		}
+
+	for (i = 0; i < sizeof(signed_test_values)/sizeof(int); ++i)
+		{
+		c = signed_test_values[i];
+		for (j = 0; j < sizeof(signed_test_values)/sizeof(int); ++j)
+			{
+			d = signed_test_values[j];
+			num_failed += test_select_int(c, d);
+			num_failed += test_eq_int(c, d);
+			num_failed += test_eq_int_8(c, d);
+			num_all += 3;
+			}
+		}
+
+	for (i = 0; i < sizeof(test_values_8); ++i)
+		{
+		e = test_values_8[i];
+		for (j = 0; j < sizeof(test_values_8); ++j)
+			{
+			f = test_values_8[j];
+			num_failed += test_select_8(e, f);
+			num_all += 1;
+			}
+		}
+
+	if (!num_failed)
+		{
+		fprintf(stdout, "ok (ran %d tests)\n", num_all);
+		return EXIT_SUCCESS;
+		}
+	else
+		{
+		fprintf(stdout, "%d of %d tests failed!\n", num_failed, num_all);
+		return EXIT_FAILURE;
+		}
+	}

Modified: trunk/crypto/openssl/crypto/ec/ec_key.c
===================================================================
--- trunk/crypto/openssl/crypto/ec/ec_key.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/crypto/ec/ec_key.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -64,7 +64,6 @@
 #include <string.h>
 #include "ec_lcl.h"
 #include <openssl/err.h>
-#include <string.h>
 
 EC_KEY *EC_KEY_new(void)
 	{

Modified: trunk/crypto/openssl/crypto/ec/ecp_smpl.c
===================================================================
--- trunk/crypto/openssl/crypto/ec/ecp_smpl.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/crypto/ec/ecp_smpl.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -1676,8 +1676,8 @@
 		{
 		for (i = 0; i < num; i++)
 			{
-			if (prod_Z[i] != NULL)
-				BN_clear_free(prod_Z[i]);
+			if (prod_Z[i] == NULL) break;
+			BN_clear_free(prod_Z[i]);
 			}
 		OPENSSL_free(prod_Z);
 		}

Modified: trunk/crypto/openssl/crypto/err/openssl.ec
===================================================================
--- trunk/crypto/openssl/crypto/err/openssl.ec	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/crypto/err/openssl.ec	2014-10-28 11:53:50 UTC (rev 6897)
@@ -69,6 +69,7 @@
 R SSL_R_TLSV1_ALERT_PROTOCOL_VERSION		1070
 R SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY	1071
 R SSL_R_TLSV1_ALERT_INTERNAL_ERROR		1080
+R SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK	1086
 R SSL_R_TLSV1_ALERT_USER_CANCELLED		1090
 R SSL_R_TLSV1_ALERT_NO_RENEGOTIATION		1100
 R SSL_R_TLSV1_UNSUPPORTED_EXTENSION		1110

Modified: trunk/crypto/openssl/crypto/evp/Makefile
===================================================================
--- trunk/crypto/openssl/crypto/evp/Makefile	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/crypto/evp/Makefile	2014-10-28 11:53:50 UTC (rev 6897)
@@ -385,7 +385,8 @@
 evp_enc.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
 evp_enc.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
 evp_enc.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-evp_enc.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_enc.c evp_locl.h
+evp_enc.o: ../../include/openssl/x509_vfy.h ../constant_time_locl.h
+evp_enc.o: ../cryptlib.h evp_enc.c evp_locl.h
 evp_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 evp_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 evp_err.o: ../../include/openssl/err.h ../../include/openssl/evp.h

Modified: trunk/crypto/openssl/crypto/evp/evp_enc.c
===================================================================
--- trunk/crypto/openssl/crypto/evp/evp_enc.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/crypto/evp/evp_enc.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -64,6 +64,7 @@
 #ifndef OPENSSL_NO_ENGINE
 #include <openssl/engine.h>
 #endif
+#include "../constant_time_locl.h"
 #include "evp_locl.h"
 
 #ifdef OPENSSL_FIPS
@@ -301,11 +302,11 @@
 
 int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
 	{
-	int i,n;
-	unsigned int b;
+	unsigned int i, b;
+	unsigned char pad, padding_good;
 
 	*outl=0;
-	b=ctx->cipher->block_size;
+	b=(unsigned int)(ctx->cipher->block_size);
 	if (ctx->flags & EVP_CIPH_NO_PADDING)
 		{
 		if(ctx->buf_len)
@@ -324,28 +325,34 @@
 			return(0);
 			}
 		OPENSSL_assert(b <= sizeof ctx->final);
-		n=ctx->final[b-1];
-		if (n == 0 || n > (int)b)
+		pad=ctx->final[b-1];
+
+		padding_good = (unsigned char)(~constant_time_is_zero_8(pad));
+		padding_good &= constant_time_ge_8(b, pad);
+
+                for (i = 1; i < b; ++i)
 			{
-			EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
-			return(0);
+			unsigned char is_pad_index = constant_time_lt_8(i, pad);
+			unsigned char pad_byte_good = constant_time_eq_8(ctx->final[b-i-1], pad);
+			padding_good &= constant_time_select_8(is_pad_index, pad_byte_good, 0xff);
 			}
-		for (i=0; i<n; i++)
-			{
-			if (ctx->final[--b] != n)
-				{
-				EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,EVP_R_BAD_DECRYPT);
-				return(0);
-				}
-			}
-		n=ctx->cipher->block_size-n;
-		for (i=0; i<n; i++)
-			out[i]=ctx->final[i];
-		*outl=n;
+
+		/*
+		 * At least 1 byte is always padding, so we always write b - 1
+		 * bytes to avoid a timing leak. The caller is required to have |b|
+		 * bytes space in |out| by the API contract.
+		 */
+		for (i = 0; i < b - 1; ++i)
+			out[i] = ctx->final[i] & padding_good;
+		/* Safe cast: for a good padding, EVP_MAX_IV_LENGTH >= b >= pad */
+		*outl = padding_good & ((unsigned char)(b - pad));
+		return padding_good & 1;
 		}
 	else
-		*outl=0;
-	return(1);
+		{
+		*outl = 0;
+		return 1;
+		}
 	}
 
 void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)

Modified: trunk/crypto/openssl/crypto/opensslv.h
===================================================================
--- trunk/crypto/openssl/crypto/opensslv.h	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/crypto/opensslv.h	2014-10-28 11:53:50 UTC (rev 6897)
@@ -25,11 +25,11 @@
  * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
  *  major minor fix final patch/beta)
  */
-#define OPENSSL_VERSION_NUMBER	0x009081bfL
+#define OPENSSL_VERSION_NUMBER	0x009081cfL
 #ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT	"OpenSSL 0.9.8zb-fips 6 Aug 2014"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 0.9.8zc-fips 15 Oct 2014"
 #else
-#define OPENSSL_VERSION_TEXT	"OpenSSL 0.9.8zb 6 Aug 2014"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 0.9.8zc 15 Oct 2014"
 #endif
 #define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
 

Modified: trunk/crypto/openssl/crypto/rsa/Makefile
===================================================================
--- trunk/crypto/openssl/crypto/rsa/Makefile	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/crypto/rsa/Makefile	2014-10-28 11:53:50 UTC (rev 6897)
@@ -189,7 +189,7 @@
 rsa_oaep.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
 rsa_oaep.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 rsa_oaep.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_oaep.o: ../cryptlib.h rsa_oaep.c
+rsa_oaep.o: ../constant_time_locl.h ../cryptlib.h rsa_oaep.c
 rsa_pk1.o: ../../e_os.h ../../include/openssl/asn1.h
 rsa_pk1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 rsa_pk1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
@@ -198,7 +198,8 @@
 rsa_pk1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 rsa_pk1.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
 rsa_pk1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-rsa_pk1.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_pk1.c
+rsa_pk1.o: ../../include/openssl/symhacks.h ../constant_time_locl.h
+rsa_pk1.o: ../cryptlib.h rsa_pk1.c
 rsa_pss.o: ../../e_os.h ../../include/openssl/asn1.h
 rsa_pss.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 rsa_pss.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h

Modified: trunk/crypto/openssl/crypto/rsa/rsa.h
===================================================================
--- trunk/crypto/openssl/crypto/rsa/rsa.h	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/crypto/rsa/rsa.h	2014-10-28 11:53:50 UTC (rev 6897)
@@ -479,6 +479,7 @@
 #define RSA_R_OAEP_DECODING_ERROR			 121
 #define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE	 142
 #define RSA_R_PADDING_CHECK_FAILED			 114
+#define RSA_R_PKCS_DECODING_ERROR			 159
 #define RSA_R_P_NOT_PRIME				 128
 #define RSA_R_Q_NOT_PRIME				 129
 #define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED		 130

Modified: trunk/crypto/openssl/crypto/rsa/rsa_err.c
===================================================================
--- trunk/crypto/openssl/crypto/rsa/rsa_err.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/crypto/rsa/rsa_err.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -151,6 +151,7 @@
 {ERR_REASON(RSA_R_OAEP_DECODING_ERROR)   ,"oaep decoding error"},
 {ERR_REASON(RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE),"operation not allowed in fips mode"},
 {ERR_REASON(RSA_R_PADDING_CHECK_FAILED)  ,"padding check failed"},
+{ERR_REASON(RSA_R_PKCS_DECODING_ERROR)   ,"pkcs decoding error"},
 {ERR_REASON(RSA_R_P_NOT_PRIME)           ,"p not prime"},
 {ERR_REASON(RSA_R_Q_NOT_PRIME)           ,"q not prime"},
 {ERR_REASON(RSA_R_RSA_OPERATIONS_NOT_SUPPORTED),"rsa operations not supported"},

Modified: trunk/crypto/openssl/crypto/rsa/rsa_oaep.c
===================================================================
--- trunk/crypto/openssl/crypto/rsa/rsa_oaep.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/crypto/rsa/rsa_oaep.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -18,6 +18,7 @@
  * an equivalent notion.
  */
 
+#include "../constant_time_locl.h"
 
 #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
 #include <stdio.h>
@@ -92,51 +93,62 @@
 	const unsigned char *from, int flen, int num,
 	const unsigned char *param, int plen)
 	{
-	int i, dblen, mlen = -1;
-	const unsigned char *maskeddb;
-	int lzero;
-	unsigned char *db = NULL, seed[SHA_DIGEST_LENGTH], phash[SHA_DIGEST_LENGTH];
-	unsigned char *padded_from;
-	int bad = 0;
+	int i, dblen, mlen = -1, one_index = 0, msg_index;
+	unsigned int good, found_one_byte;
+	const unsigned char *maskedseed, *maskeddb;
+	/* |em| is the encoded message, zero-padded to exactly |num| bytes:
+	 * em = Y || maskedSeed || maskedDB */
+	unsigned char *db = NULL, *em = NULL, seed[EVP_MAX_MD_SIZE],
+		phash[EVP_MAX_MD_SIZE];
 
-	if (--num < 2 * SHA_DIGEST_LENGTH + 1)
-		/* 'num' is the length of the modulus, i.e. does not depend on the
-		 * particular ciphertext. */
+        if (tlen <= 0 || flen <= 0)
+		return -1;
+
+	/*
+	 * |num| is the length of the modulus; |flen| is the length of the
+	 * encoded message. Therefore, for any |from| that was obtained by
+	 * decrypting a ciphertext, we must have |flen| <= |num|. Similarly,
+	 * num < 2 * SHA_DIGEST_LENGTH + 2 must hold for the modulus
+	 * irrespective of the ciphertext, see PKCS #1 v2.2, section 7.1.2.
+	 * This does not leak any side-channel information.
+	 */
+	if (num < flen || num < 2 * SHA_DIGEST_LENGTH + 2)
 		goto decoding_err;
 
-	lzero = num - flen;
-	if (lzero < 0)
+	dblen = num - SHA_DIGEST_LENGTH - 1;
+	db = OPENSSL_malloc(dblen);
+	em = OPENSSL_malloc(num);
+	if (db == NULL || em == NULL)
 		{
-		/* signalling this error immediately after detection might allow
-		 * for side-channel attacks (e.g. timing if 'plen' is huge
-		 * -- cf. James H. Manger, "A Chosen Ciphertext Attack on RSA Optimal
-		 * Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001),
-		 * so we use a 'bad' flag */
-		bad = 1;
-		lzero = 0;
-		flen = num; /* don't overflow the memcpy to padded_from */
-		}
-
-	dblen = num - SHA_DIGEST_LENGTH;
-	db = OPENSSL_malloc(dblen + num);
-	if (db == NULL)
-		{
 		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, ERR_R_MALLOC_FAILURE);
-		return -1;
+		goto cleanup;
 		}
 
-	/* Always do this zero-padding copy (even when lzero == 0)
-	 * to avoid leaking timing info about the value of lzero. */
-	padded_from = db + dblen;
-	memset(padded_from, 0, lzero);
-	memcpy(padded_from + lzero, from, flen);
+	/*
+	 * Always do this zero-padding copy (even when num == flen) to avoid
+	 * leaking that information. The copy still leaks some side-channel
+	 * information, but it's impossible to have a fixed  memory access
+	 * pattern since we can't read out of the bounds of |from|.
+	 *
+	 * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL.
+	 */
+	memset(em, 0, num);
+	memcpy(em + num - flen, from, flen);
 
-	maskeddb = padded_from + SHA_DIGEST_LENGTH;
+	/*
+	 * The first byte must be zero, however we must not leak if this is
+	 * true. See James H. Manger, "A Chosen Ciphertext  Attack on RSA
+	 * Optimal Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001).
+	 */
+	good = constant_time_is_zero(em[0]);
 
+	maskedseed = em + 1;
+	maskeddb = em + 1 + SHA_DIGEST_LENGTH;
+
 	MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen);
 	for (i = 0; i < SHA_DIGEST_LENGTH; i++)
-		seed[i] ^= padded_from[i];
-  
+		seed[i] ^= maskedseed[i];
+
 	MGF1(db, dblen, seed, SHA_DIGEST_LENGTH);
 	for (i = 0; i < dblen; i++)
 		db[i] ^= maskeddb[i];
@@ -143,38 +155,52 @@
 
 	EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL);
 
-	if (CRYPTO_memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
+	good &= constant_time_is_zero(CRYPTO_memcmp(db, phash, SHA_DIGEST_LENGTH));
+
+	found_one_byte = 0;
+	for (i = SHA_DIGEST_LENGTH; i < dblen; i++)
+		{
+		/* Padding consists of a number of 0-bytes, followed by a 1. */
+		unsigned int equals1 = constant_time_eq(db[i], 1);
+		unsigned int equals0 = constant_time_is_zero(db[i]);
+		one_index = constant_time_select_int(~found_one_byte & equals1,
+			i, one_index);
+		found_one_byte |= equals1;
+		good &= (found_one_byte | equals0);
+		}
+
+	good &= found_one_byte;
+
+	/*
+	 * At this point |good| is zero unless the plaintext was valid,
+	 * so plaintext-awareness ensures timing side-channels are no longer a
+	 * concern.
+	 */
+	if (!good)
 		goto decoding_err;
+
+	msg_index = one_index + 1;
+	mlen = dblen - msg_index;
+
+	if (tlen < mlen)
+		{
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE);
+		mlen = -1;
+		}
 	else
 		{
-		for (i = SHA_DIGEST_LENGTH; i < dblen; i++)
-			if (db[i] != 0x00)
-				break;
-		if (i == dblen || db[i] != 0x01)
-			goto decoding_err;
-		else
-			{
-			/* everything looks OK */
-
-			mlen = dblen - ++i;
-			if (tlen < mlen)
-				{
-				RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE);
-				mlen = -1;
-				}
-			else
-				memcpy(to, db + i, mlen);
-			}
+		memcpy(to, db + msg_index, mlen);
+		goto cleanup;
 		}
-	OPENSSL_free(db);
-	return mlen;
 
 decoding_err:
-	/* to avoid chosen ciphertext attacks, the error message should not reveal
-	 * which kind of decoding error happened */
+	/* To avoid chosen ciphertext attacks, the error message should not reveal
+	 * which kind of decoding error happened. */
 	RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_OAEP_DECODING_ERROR);
+cleanup:
 	if (db != NULL) OPENSSL_free(db);
-	return -1;
+	if (em != NULL) OPENSSL_free(em);
+	return mlen;
 	}
 
 int PKCS1_MGF1(unsigned char *mask, long len,

Modified: trunk/crypto/openssl/crypto/rsa/rsa_pk1.c
===================================================================
--- trunk/crypto/openssl/crypto/rsa/rsa_pk1.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/crypto/rsa/rsa_pk1.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -56,6 +56,8 @@
  * [including the GNU Public Licence.]
  */
 
+#include "../constant_time_locl.h"
+
 #include <stdio.h>
 #include "cryptlib.h"
 #include <openssl/bn.h>
@@ -181,44 +183,87 @@
 int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen,
 	     const unsigned char *from, int flen, int num)
 	{
-	int i,j;
-	const unsigned char *p;
+	int i;
+	/* |em| is the encoded message, zero-padded to exactly |num| bytes */
+	unsigned char *em = NULL;
+	unsigned int good, found_zero_byte;
+	int zero_index = 0, msg_index, mlen = -1;
 
-	p=from;
-	if ((num != (flen+1)) || (*(p++) != 02))
+        if (tlen < 0 || flen < 0)
+		return -1;
+
+	/* PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography
+	 * Standard", section 7.2.2. */
+
+	if (flen > num)
+		goto err;
+
+	if (num < 11)
+		goto err;
+
+	em = OPENSSL_malloc(num);
+	if (em == NULL)
 		{
-		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_BLOCK_TYPE_IS_NOT_02);
-		return(-1);
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE);
+		return -1;
 		}
-#ifdef PKCS1_CHECK
-	return(num-11);
-#endif
+	memset(em, 0, num);
+	/*
+	 * Always do this zero-padding copy (even when num == flen) to avoid
+	 * leaking that information. The copy still leaks some side-channel
+	 * information, but it's impossible to have a fixed  memory access
+	 * pattern since we can't read out of the bounds of |from|.
+	 *
+	 * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL.
+	 */
+	memcpy(em + num - flen, from, flen);
 
-	/* scan over padding data */
-	j=flen-1; /* one for type. */
-	for (i=0; i<j; i++)
-		if (*(p++) == 0) break;
+	good = constant_time_is_zero(em[0]);
+	good &= constant_time_eq(em[1], 2);
 
-	if (i == j)
+	found_zero_byte = 0;
+	for (i = 2; i < num; i++)
 		{
-		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_NULL_BEFORE_BLOCK_MISSING);
-		return(-1);
+		unsigned int equals0 = constant_time_is_zero(em[i]);
+		zero_index = constant_time_select_int(~found_zero_byte & equals0, i, zero_index);
+		found_zero_byte |= equals0;
 		}
 
-	if (i < 8)
+	/*
+	 * PS must be at least 8 bytes long, and it starts two bytes into |em|.
+         * If we never found a 0-byte, then |zero_index| is 0 and the check
+	 * also fails.
+	 */
+	good &= constant_time_ge((unsigned int)(zero_index), 2 + 8);
+
+	/* Skip the zero byte. This is incorrect if we never found a zero-byte
+	 * but in this case we also do not copy the message out. */
+	msg_index = zero_index + 1;
+	mlen = num - msg_index;
+
+	/* For good measure, do this check in constant time as well; it could
+	 * leak something if |tlen| was assuming valid padding. */
+	good &= constant_time_ge((unsigned int)(tlen), (unsigned int)(mlen));
+
+	/*
+	 * We can't continue in constant-time because we need to copy the result
+	 * and we cannot fake its length. This unavoidably leaks timing
+	 * information at the API boundary.
+	 * TODO(emilia): this could be addressed at the call site,
+	 * see BoringSSL commit 0aa0767340baf925bda4804882aab0cb974b2d26.
+	 */
+	if (!good)
 		{
-		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_BAD_PAD_BYTE_COUNT);
-		return(-1);
+		mlen = -1;
+		goto err;
 		}
-	i++; /* Skip over the '\0' */
-	j-=i;
-	if (j > tlen)
-		{
-		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_DATA_TOO_LARGE);
-		return(-1);
-		}
-	memcpy(to,p,(unsigned int)j);
 
-	return(j);
+	memcpy(to, em + msg_index, mlen);
+
+err:
+	if (em != NULL)
+		OPENSSL_free(em);
+	if (mlen == -1)
+		RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, RSA_R_PKCS_DECODING_ERROR);
+	return mlen;
 	}
-

Modified: trunk/crypto/openssl/crypto/rsa/rsa_sign.c
===================================================================
--- trunk/crypto/openssl/crypto/rsa/rsa_sign.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/crypto/rsa/rsa_sign.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -155,6 +155,25 @@
 	return(ret);
 	}
 
+/*
+ * Check DigestInfo structure does not contain extraneous data by reencoding
+ * using DER and checking encoding against original. 
+ */
+static int rsa_check_digestinfo(X509_SIG *sig, const unsigned char *dinfo, int dinfolen)
+	{
+	unsigned char *der = NULL;
+	int derlen;
+	int ret = 0;
+	derlen = i2d_X509_SIG(sig, &der);
+	if (derlen <= 0)
+		return 0;
+	if (derlen == dinfolen && !memcmp(dinfo, der, derlen))
+		ret = 1;
+	OPENSSL_cleanse(der, derlen);
+	OPENSSL_free(der);
+	return ret;
+	}
+
 int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,
 	     unsigned char *sigbuf, unsigned int siglen, RSA *rsa)
 	{
@@ -215,7 +234,7 @@
 		if (sig == NULL) goto err;
 
 		/* Excess data can be used to create forgeries */
-		if(p != s+i)
+		if(p != s+i || !rsa_check_digestinfo(sig, s, i))
 			{
 			RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
 			goto err;

Modified: trunk/crypto/openssl/doc/apps/s_client.pod
===================================================================
--- trunk/crypto/openssl/doc/apps/s_client.pod	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/doc/apps/s_client.pod	2014-10-28 11:53:50 UTC (rev 6897)
@@ -50,6 +50,7 @@
 [B<-no_ssl2>]
 [B<-no_ssl3>]
 [B<-no_tls1>]
+[B<-fallback_scsv>]
 [B<-bugs>]
 [B<-cipher cipherlist>]
 [B<-starttls protocol>]
@@ -198,11 +199,14 @@
 the initial handshake uses a method which should be compatible with all
 servers and permit them to use SSL v3, SSL v2 or TLS as appropriate.
 
-Unfortunately there are a lot of ancient and broken servers in use which
+Unfortunately there are still ancient and broken servers in use which
 cannot handle this technique and will fail to connect. Some servers only
-work if TLS is turned off with the B<-no_tls> option others will only
-support SSL v2 and may need the B<-ssl2> option.
+work if TLS is turned off.
 
+=item B<-fallback_scsv>
+
+Send TLS_FALLBACK_SCSV in the ClientHello.
+
 =item B<-bugs>
 
 there are several known bug in SSL and TLS implementations. Adding this

Modified: trunk/crypto/openssl/doc/ssl/SSL_CTX_set_mode.pod
===================================================================
--- trunk/crypto/openssl/doc/ssl/SSL_CTX_set_mode.pod	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/doc/ssl/SSL_CTX_set_mode.pod	2014-10-28 11:53:50 UTC (rev 6897)
@@ -61,6 +61,12 @@
 flag SSL_MODE_AUTO_RETRY will cause read/write operations to only
 return after the handshake and successful completion.
 
+=item SSL_MODE_FALLBACK_SCSV
+
+Send TLS_FALLBACK_SCSV in the ClientHello.
+To be set by applications that reconnect with a downgraded protocol
+version; see draft-ietf-tls-downgrade-scsv-00 for details.
+
 =back
 
 =head1 RETURN VALUES

Modified: trunk/crypto/openssl/e_os.h
===================================================================
--- trunk/crypto/openssl/e_os.h	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/e_os.h	2014-10-28 11:53:50 UTC (rev 6897)
@@ -360,8 +360,17 @@
 #    define DEFAULT_HOME  "C:"
 #  endif
 
-#else /* The non-microsoft world world */
+/*
+ * Visual Studio: inline is available in C++ only, however
+ * __inline is available for C, see
+ * http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx
+ */
+#if defined(_MSC_VER) && !defined(__cplusplus) && !defined(inline)
+#  define inline __inline
+#endif
 
+#else /* The non-microsoft world */
+
 #  ifdef OPENSSL_SYS_VMS
 #    define VMS 1
   /* some programs don't include stdlib, so exit() and others give implicit 
@@ -707,4 +716,3 @@
 #endif
 
 #endif
-

Modified: trunk/crypto/openssl/openssl.spec
===================================================================
--- trunk/crypto/openssl/openssl.spec	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/openssl.spec	2014-10-28 11:53:50 UTC (rev 6897)
@@ -6,7 +6,7 @@
 
 Summary: Secure Sockets Layer and cryptography libraries and tools
 Name: openssl
-Version: 0.9.8zb
+Version: 0.9.8zc
 Source0: ftp://ftp.openssl.org/source/%{name}-%{version}.tar.gz
 License: OpenSSL
 Group: System Environment/Libraries

Modified: trunk/crypto/openssl/ssl/Makefile
===================================================================
--- trunk/crypto/openssl/ssl/Makefile	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/ssl/Makefile	2014-10-28 11:53:50 UTC (rev 6897)
@@ -545,27 +545,28 @@
 s3_both.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
 s3_both.o: ../include/openssl/tls1.h ../include/openssl/x509.h
 s3_both.o: ../include/openssl/x509_vfy.h s3_both.c ssl_locl.h
-s3_cbc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s3_cbc.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s3_cbc.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s3_cbc.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
-s3_cbc.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
-s3_cbc.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-s3_cbc.o: ../include/openssl/err.h ../include/openssl/evp.h
-s3_cbc.o: ../include/openssl/fips.h ../include/openssl/hmac.h
-s3_cbc.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
-s3_cbc.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
-s3_cbc.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
-s3_cbc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-s3_cbc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-s3_cbc.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
-s3_cbc.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
-s3_cbc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s3_cbc.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s3_cbc.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s3_cbc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s3_cbc.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s3_cbc.o: ../include/openssl/x509_vfy.h s3_cbc.c ssl_locl.h
+s3_cbc.o: ../crypto/constant_time_locl.h ../e_os.h ../include/openssl/asn1.h
+s3_cbc.o: ../include/openssl/bio.h ../include/openssl/bn.h
+s3_cbc.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s3_cbc.o: ../include/openssl/crypto.h ../include/openssl/dsa.h
+s3_cbc.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
+s3_cbc.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
+s3_cbc.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
+s3_cbc.o: ../include/openssl/evp.h ../include/openssl/fips.h
+s3_cbc.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+s3_cbc.o: ../include/openssl/lhash.h ../include/openssl/md5.h
+s3_cbc.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s3_cbc.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s3_cbc.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s3_cbc.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s3_cbc.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
+s3_cbc.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s3_cbc.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s3_cbc.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s3_cbc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s3_cbc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s3_cbc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s3_cbc.c
+s3_cbc.o: ssl_locl.h
 s3_clnt.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 s3_clnt.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 s3_clnt.o: ../include/openssl/comp.h ../include/openssl/crypto.h
@@ -674,29 +675,29 @@
 s3_pkt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
 s3_pkt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h s3_pkt.c
 s3_pkt.o: ssl_locl.h
-s3_srvr.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
-s3_srvr.o: ../include/openssl/bn.h ../include/openssl/buffer.h
-s3_srvr.o: ../include/openssl/comp.h ../include/openssl/crypto.h
-s3_srvr.o: ../include/openssl/dh.h ../include/openssl/dsa.h
-s3_srvr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
-s3_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
-s3_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-s3_srvr.o: ../include/openssl/evp.h ../include/openssl/fips.h
-s3_srvr.o: ../include/openssl/hmac.h ../include/openssl/krb5_asn.h
-s3_srvr.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
-s3_srvr.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
-s3_srvr.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
-s3_srvr.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-s3_srvr.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-s3_srvr.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
-s3_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
-s3_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-s3_srvr.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-s3_srvr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-s3_srvr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-s3_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-s3_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h kssl_lcl.h
-s3_srvr.o: s3_srvr.c ssl_locl.h
+s3_srvr.o: ../crypto/constant_time_locl.h ../e_os.h ../include/openssl/asn1.h
+s3_srvr.o: ../include/openssl/bio.h ../include/openssl/bn.h
+s3_srvr.o: ../include/openssl/buffer.h ../include/openssl/comp.h
+s3_srvr.o: ../include/openssl/crypto.h ../include/openssl/dh.h
+s3_srvr.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
+s3_srvr.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
+s3_srvr.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
+s3_srvr.o: ../include/openssl/err.h ../include/openssl/evp.h
+s3_srvr.o: ../include/openssl/fips.h ../include/openssl/hmac.h
+s3_srvr.o: ../include/openssl/krb5_asn.h ../include/openssl/kssl.h
+s3_srvr.o: ../include/openssl/lhash.h ../include/openssl/md5.h
+s3_srvr.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+s3_srvr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+s3_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+s3_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+s3_srvr.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
+s3_srvr.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+s3_srvr.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+s3_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+s3_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+s3_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+s3_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+s3_srvr.o: ../include/openssl/x509_vfy.h kssl_lcl.h s3_srvr.c ssl_locl.h
 ssl_algs.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 ssl_algs.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 ssl_algs.o: ../include/openssl/comp.h ../include/openssl/crypto.h

Modified: trunk/crypto/openssl/ssl/d1_lib.c
===================================================================
--- trunk/crypto/openssl/ssl/d1_lib.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/ssl/d1_lib.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -305,6 +305,16 @@
 	case DTLS_CTRL_LISTEN:
 		ret = dtls1_listen(s, parg);
 		break;
+	case SSL_CTRL_CHECK_PROTO_VERSION:
+		/* For library-internal use; checks that the current protocol
+		 * is the highest enabled version (according to s->ctx->method,
+		 * as version negotiation may have changed s->method). */
+#if DTLS_MAX_VERSION != DTLS1_VERSION
+#  error Code needs update for DTLS_method() support beyond DTLS1_VERSION.
+#endif
+		/* Just one protocol version is supported so far;
+		 * fail closed if the version is not as expected. */
+		return s->version == DTLS_MAX_VERSION;
 
 	default:
 		ret = ssl3_ctrl(s, cmd, larg, parg);

Modified: trunk/crypto/openssl/ssl/dtls1.h
===================================================================
--- trunk/crypto/openssl/ssl/dtls1.h	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/ssl/dtls1.h	2014-10-28 11:53:50 UTC (rev 6897)
@@ -80,6 +80,8 @@
 #endif
 
 #define DTLS1_VERSION			0xFEFF
+#define DTLS_MAX_VERSION		DTLS1_VERSION
+
 #define DTLS1_BAD_VER			0x0100
 
 #if 0
@@ -262,4 +264,3 @@
 }
 #endif
 #endif
-

Modified: trunk/crypto/openssl/ssl/s23_clnt.c
===================================================================
--- trunk/crypto/openssl/ssl/s23_clnt.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/ssl/s23_clnt.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -72,9 +72,11 @@
 	if (ver == SSL2_VERSION)
 		return(SSLv2_client_method());
 #endif
+#ifndef OPENSSL_NO_SSL3
 	if (ver == SSL3_VERSION)
 		return(SSLv3_client_method());
-	else if (ver == TLS1_VERSION)
+#endif
+	if (ver == TLS1_VERSION)
 		return(TLSv1_client_method());
 	else
 		return(NULL);
@@ -533,6 +535,7 @@
 		{
 		/* we have sslv3 or tls1 (server hello or alert) */
 
+#ifndef OPENSSL_NO_SSL3
 		if ((p[2] == SSL3_VERSION_MINOR) &&
 			!(s->options & SSL_OP_NO_SSLv3))
 			{
@@ -547,7 +550,9 @@
 			s->version=SSL3_VERSION;
 			s->method=SSLv3_client_method();
 			}
-		else if ((p[2] == TLS1_VERSION_MINOR) &&
+		else
+#endif
+		if ((p[2] == TLS1_VERSION_MINOR) &&
 			!(s->options & SSL_OP_NO_TLSv1))
 			{
 			s->version=TLS1_VERSION;
@@ -559,6 +564,9 @@
 			goto err;
 			}
 
+		/* ensure that TLS_MAX_VERSION is up-to-date */
+		OPENSSL_assert(s->version <= TLS_MAX_VERSION);
+
 		if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING)
 			{
 			/* fatal alert */

Modified: trunk/crypto/openssl/ssl/s23_srvr.c
===================================================================
--- trunk/crypto/openssl/ssl/s23_srvr.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/ssl/s23_srvr.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -124,9 +124,11 @@
 	if (ver == SSL2_VERSION)
 		return(SSLv2_server_method());
 #endif
+#ifndef OPENSSL_NO_SSL3
 	if (ver == SSL3_VERSION)
 		return(SSLv3_server_method());
-	else if (ver == TLS1_VERSION)
+#endif
+	if (ver == TLS1_VERSION)
 		return(TLSv1_server_method());
 	else
 		return(NULL);
@@ -398,6 +400,9 @@
 		}
 #endif
 
+	/* ensure that TLS_MAX_VERSION is up-to-date */
+	OPENSSL_assert(s->version <= TLS_MAX_VERSION);
+
 	if (s->state == SSL23_ST_SR_CLNT_HELLO_B)
 		{
 		/* we have SSLv3/TLSv1 in an SSLv2 header
@@ -554,6 +559,12 @@
 	if ((type == 2) || (type == 3))
 		{
 		/* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */
+                s->method = ssl23_get_server_method(s->version);
+		if (s->method == NULL)
+			{
+			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_UNSUPPORTED_PROTOCOL);
+			goto err;
+			}
 
 		if (!ssl_init_wbio_buffer(s,1)) goto err;
 
@@ -577,11 +588,6 @@
 			s->s3->rbuf.left=0;
 			s->s3->rbuf.offset=0;
 			}
-
-		if (s->version == TLS1_VERSION)
-			s->method = TLSv1_server_method();
-		else
-			s->method = SSLv3_server_method();
 #if 0 /* ssl3_get_client_hello does this */
 		s->client_version=(v[0]<<8)|v[1];
 #endif

Modified: trunk/crypto/openssl/ssl/s2_lib.c
===================================================================
--- trunk/crypto/openssl/ssl/s2_lib.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/ssl/s2_lib.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -314,6 +314,8 @@
 	case SSL_CTRL_GET_SESSION_REUSED:
 		ret=s->hit;
 		break;
+	case SSL_CTRL_CHECK_PROTO_VERSION:
+		return ssl3_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, larg, parg);
 	default:
 		break;
 		}
@@ -362,7 +364,7 @@
 	if (p != NULL)
 		{
 		l=c->id;
-		if ((l & 0xff000000) != 0x02000000) return(0);
+		if ((l & 0xff000000) != 0x02000000 && l != SSL3_CK_FALLBACK_SCSV) return(0);
 		p[0]=((unsigned char)(l>>16L))&0xFF;
 		p[1]=((unsigned char)(l>> 8L))&0xFF;
 		p[2]=((unsigned char)(l     ))&0xFF;

Modified: trunk/crypto/openssl/ssl/s3_cbc.c
===================================================================
--- trunk/crypto/openssl/ssl/s3_cbc.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/ssl/s3_cbc.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -53,6 +53,7 @@
  *
  */
 
+#include "../crypto/constant_time_locl.h"
 #include "ssl_locl.h"
 
 #include <openssl/md5.h>
@@ -67,37 +68,6 @@
  * supported by TLS.) */
 #define MAX_HASH_BLOCK_SIZE 128
 
-/* Some utility functions are needed:
- *
- * These macros return the given value with the MSB copied to all the other
- * bits. They use the fact that arithmetic shift shifts-in the sign bit.
- * However, this is not ensured by the C standard so you may need to replace
- * them with something else on odd CPUs. */
-#define DUPLICATE_MSB_TO_ALL(x) ( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) )
-#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x)))
-
-/* constant_time_lt returns 0xff if a<b and 0x00 otherwise. */
-static unsigned constant_time_lt(unsigned a, unsigned b)
-	{
-	a -= b;
-	return DUPLICATE_MSB_TO_ALL(a);
-	}
-
-/* constant_time_ge returns 0xff if a>=b and 0x00 otherwise. */
-static unsigned constant_time_ge(unsigned a, unsigned b)
-	{
-	a -= b;
-	return DUPLICATE_MSB_TO_ALL(~a);
-	}
-
-/* constant_time_eq_8 returns 0xff if a==b and 0x00 otherwise. */
-static unsigned char constant_time_eq_8(unsigned a, unsigned b)
-	{
-	unsigned c = a ^ b;
-	c--;
-	return DUPLICATE_MSB_TO_ALL_8(c);
-	}
-
 /* ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC
  * record in |rec| by updating |rec->length| in constant time.
  *
@@ -126,8 +96,8 @@
 	padding_length = good & (padding_length+1);
 	rec->length -= padding_length;
 	rec->type |= padding_length<<8;	/* kludge: pass padding length */
-	return (int)((good & 1) | (~good & -1));
-}
+	return constant_time_select_int(good, 1, -1);
+	}
 
 /* tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC
  * record in |rec| in constant time and returns 1 if the padding is valid and
@@ -201,7 +171,7 @@
 
 	for (i = 0; i < to_check; i++)
 		{
-		unsigned char mask = constant_time_ge(padding_length, i);
+		unsigned char mask = constant_time_ge_8(padding_length, i);
 		unsigned char b = rec->data[rec->length-1-i];
 		/* The final |padding_length+1| bytes should all have the value
 		 * |padding_length|. Therefore the XOR should be zero. */
@@ -209,20 +179,14 @@
 		}
 
 	/* If any of the final |padding_length+1| bytes had the wrong value,
-	 * one or more of the lower eight bits of |good| will be cleared. We
-	 * AND the bottom 8 bits together and duplicate the result to all the
-	 * bits. */
-	good &= good >> 4;
-	good &= good >> 2;
-	good &= good >> 1;
-	good <<= sizeof(good)*8-1;
-	good = DUPLICATE_MSB_TO_ALL(good);
-
+	 * one or more of the lower eight bits of |good| will be cleared.
+	 */
+	good = constant_time_eq(0xff, good & 0xff);
 	padding_length = good & (padding_length+1);
 	rec->length -= padding_length;
 	rec->type |= padding_length<<8;	/* kludge: pass padding length */
 
-	return (int)((good & 1) | (~good & -1));
+	return constant_time_select_int(good, 1, -1);
 	}
 
 /* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in
@@ -289,8 +253,8 @@
 	memset(rotated_mac, 0, md_size);
 	for (i = scan_start, j = 0; i < orig_len; i++)
 		{
-		unsigned char mac_started = constant_time_ge(i, mac_start);
-		unsigned char mac_ended = constant_time_ge(i, mac_end);
+		unsigned char mac_started = constant_time_ge_8(i, mac_start);
+		unsigned char mac_ended = constant_time_ge_8(i, mac_end);
 		unsigned char b = rec->data[i];
 		rotated_mac[j++] |= b & mac_started & ~mac_ended;
 		j &= constant_time_lt(j,md_size);
@@ -676,12 +640,12 @@
 				b = data[k-header_length];
 			k++;
 
-			is_past_c = is_block_a & constant_time_ge(j, c);
-			is_past_cp1 = is_block_a & constant_time_ge(j, c+1);
+			is_past_c = is_block_a & constant_time_ge_8(j, c);
+			is_past_cp1 = is_block_a & constant_time_ge_8(j, c+1);
 			/* If this is the block containing the end of the
 			 * application data, and we are at the offset for the
 			 * 0x80 value, then overwrite b with 0x80. */
-			b = (b&~is_past_c) | (0x80&is_past_c);
+                        b =  constant_time_select_8(is_past_c, 0x80, b);
 			/* If this the the block containing the end of the
 			 * application data and we're past the 0x80 value then
 			 * just write zero. */
@@ -697,7 +661,8 @@
 			if (j >= md_block_size - md_length_size)
 				{
 				/* If this is index_b, write a length byte. */
-				b = (b&~is_block_b) | (is_block_b&length_bytes[j-(md_block_size-md_length_size)]);
+				b = constant_time_select_8(
+					is_block_b, length_bytes[j-(md_block_size-md_length_size)], b);
 				}
 			block[j] = b;
 			}

Modified: trunk/crypto/openssl/ssl/s3_clnt.c
===================================================================
--- trunk/crypto/openssl/ssl/s3_clnt.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/ssl/s3_clnt.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -1095,8 +1095,8 @@
 #endif
 	EVP_MD_CTX md_ctx;
 	unsigned char *param,*p;
-	int al,i,j,param_len,ok;
-	long n,alg;
+	int al,j,ok;
+	long i,param_len,n,alg;
 	EVP_PKEY *pkey=NULL;
 #ifndef OPENSSL_NO_RSA
 	RSA *rsa=NULL;
@@ -1160,10 +1160,12 @@
 		s->session->sess_cert=ssl_sess_cert_new();
 		}
 
+	/* Total length of the parameters including the length prefix */
 	param_len=0;
 	alg=s->s3->tmp.new_cipher->algorithms;
 	EVP_MD_CTX_init(&md_ctx);
 
+	al=SSL_AD_DECODE_ERROR;
 #ifndef OPENSSL_NO_RSA
 	if (alg & SSL_kRSA)
 		{
@@ -1172,14 +1174,23 @@
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE);
 			goto err;
 			}
-		n2s(p,i);
-		param_len=i+2;
+
+		param_len = 2;
 		if (param_len > n)
 			{
-			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+				SSL_R_LENGTH_TOO_SHORT);
+			goto f_err;
+			}
+		n2s(p,i);
+
+		if (i > n - param_len)
+			{
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_MODULUS_LENGTH);
 			goto f_err;
 			}
+		param_len += i;
+
 		if (!(rsa->n=BN_bin2bn(p,i,rsa->n)))
 			{
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
@@ -1187,14 +1198,23 @@
 			}
 		p+=i;
 
+		if (2 > n - param_len)
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+				SSL_R_LENGTH_TOO_SHORT);
+			goto f_err;
+			}
+		param_len += 2;
+
 		n2s(p,i);
-		param_len+=i+2;
-		if (param_len > n)
+
+		if (i > n - param_len)
 			{
-			al=SSL_AD_DECODE_ERROR;
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_RSA_E_LENGTH);
 			goto f_err;
 			}
+		param_len += i;
+
 		if (!(rsa->e=BN_bin2bn(p,i,rsa->e)))
 			{
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
@@ -1226,14 +1246,23 @@
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_DH_LIB);
 			goto err;
 			}
-		n2s(p,i);
-		param_len=i+2;
+
+		param_len = 2;
 		if (param_len > n)
 			{
-			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+				SSL_R_LENGTH_TOO_SHORT);
+			goto f_err;
+			}
+		n2s(p,i);
+
+		if (i > n - param_len)
+			{
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_P_LENGTH);
 			goto f_err;
 			}
+		param_len += i;
+
 		if (!(dh->p=BN_bin2bn(p,i,NULL)))
 			{
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
@@ -1241,14 +1270,23 @@
 			}
 		p+=i;
 
+		if (2 > n - param_len)
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+				SSL_R_LENGTH_TOO_SHORT);
+			goto f_err;
+			}
+		param_len += 2;
+
 		n2s(p,i);
-		param_len+=i+2;
-		if (param_len > n)
+
+		if (i > n - param_len)
 			{
-			al=SSL_AD_DECODE_ERROR;
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_G_LENGTH);
 			goto f_err;
 			}
+		param_len += i;
+
 		if (!(dh->g=BN_bin2bn(p,i,NULL)))
 			{
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
@@ -1256,14 +1294,23 @@
 			}
 		p+=i;
 
+		if (2 > n - param_len)
+			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+				SSL_R_LENGTH_TOO_SHORT);
+			goto f_err;
+			}
+		param_len += 2;
+
 		n2s(p,i);
-		param_len+=i+2;
-		if (param_len > n)
+
+		if (i > n - param_len)
 			{
-			al=SSL_AD_DECODE_ERROR;
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_DH_PUB_KEY_LENGTH);
 			goto f_err;
 			}
+		param_len += i;
+
 		if (!(dh->pub_key=BN_bin2bn(p,i,NULL)))
 			{
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_BN_LIB);
@@ -1315,13 +1362,20 @@
 		 */
 
 		/* XXX: For now we only support named (not generic) curves
-		 * and the ECParameters in this case is just three bytes.
+		 * and the ECParameters in this case is just three bytes. We
+		 * also need one byte for the length of the encoded point
 		 */
-		param_len=3;
-		if ((param_len > n) ||
-		    (*p != NAMED_CURVE_TYPE) || 
-		    ((curve_nid = curve_id2nid(*(p + 2))) == 0)) 
+		param_len=4;
+		if (param_len > n)
 			{
+			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
+				SSL_R_LENGTH_TOO_SHORT);
+			goto f_err;
+			}
+
+		if ((*p != NAMED_CURVE_TYPE) || 
+		    ((curve_nid = curve_id2nid(*(p + 2))) == 0))
+			{
 			al=SSL_AD_INTERNAL_ERROR;
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
 			goto f_err;
@@ -1362,15 +1416,15 @@
 
 		encoded_pt_len = *p;  /* length of encoded point */
 		p+=1;
-		param_len += (1 + encoded_pt_len);
-		if ((param_len > n) ||
+
+		if ((encoded_pt_len > n - param_len) ||
 		    (EC_POINT_oct2point(group, srvr_ecpoint, 
 			p, encoded_pt_len, bn_ctx) == 0))
 			{
-			al=SSL_AD_DECODE_ERROR;
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_ECPOINT);
 			goto f_err;
 			}
+		param_len += encoded_pt_len;
 
 		n-=param_len;
 		p+=encoded_pt_len;
@@ -1421,10 +1475,10 @@
 		n-=2;
 		j=EVP_PKEY_size(pkey);
 
+		/* Check signature length. If n is 0 then signature is empty */
 		if ((i != n) || (n > j) || (n <= 0))
 			{
 			/* wrong packet length */
-			al=SSL_AD_DECODE_ERROR;
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_WRONG_SIGNATURE_LENGTH);
 			goto f_err;
 			}
@@ -1433,6 +1487,7 @@
 		if (pkey->type == EVP_PKEY_RSA)
 			{
 			int num;
+			unsigned int size;
 
 			j=0;
 			q=md_buf;
@@ -1445,9 +1500,9 @@
 				EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
 				EVP_DigestUpdate(&md_ctx,&(s->s3->server_random[0]),SSL3_RANDOM_SIZE);
 				EVP_DigestUpdate(&md_ctx,param,param_len);
-				EVP_DigestFinal_ex(&md_ctx,q,(unsigned int *)&i);
-				q+=i;
-				j+=i;
+				EVP_DigestFinal_ex(&md_ctx,q,&size);
+				q+=size;
+				j+=size;
 				}
 			i=RSA_verify(NID_md5_sha1, md_buf, j, p, n,
 								pkey->pkey.rsa);
@@ -1518,7 +1573,6 @@
 			}
 		if (n != 0)
 			{
-			al=SSL_AD_DECODE_ERROR;
 			SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_EXTRA_DATA_IN_MESSAGE);
 			goto f_err;
 			}

Modified: trunk/crypto/openssl/ssl/s3_enc.c
===================================================================
--- trunk/crypto/openssl/ssl/s3_enc.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/ssl/s3_enc.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -764,7 +764,7 @@
 	case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(SSL3_AD_HANDSHAKE_FAILURE);
 	case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(SSL3_AD_HANDSHAKE_FAILURE);
 	case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
+	case SSL_AD_INAPPROPRIATE_FALLBACK:return(TLS1_AD_INAPPROPRIATE_FALLBACK);
 	default:			return(-1);
 		}
 	}
-

Modified: trunk/crypto/openssl/ssl/s3_lib.c
===================================================================
--- trunk/crypto/openssl/ssl/s3_lib.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/ssl/s3_lib.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -1986,6 +1986,29 @@
 		break;
 
 #endif /* !OPENSSL_NO_TLSEXT */
+
+	case SSL_CTRL_CHECK_PROTO_VERSION:
+		/* For library-internal use; checks that the current protocol
+		 * is the highest enabled version (according to s->ctx->method,
+		 * as version negotiation may have changed s->method). */
+		if (s->version == s->ctx->method->version)
+			return 1;
+		/* Apparently we're using a version-flexible SSL_METHOD
+		 * (not at its highest protocol version). */
+		if (s->ctx->method->version == SSLv23_method()->version)
+			{
+#if TLS_MAX_VERSION != TLS1_VERSION
+#  error Code needs update for SSLv23_method() support beyond TLS1_VERSION.
+#endif
+			if (!(s->options & SSL_OP_NO_TLSv1))
+				return s->version == TLS1_VERSION;
+			if (!(s->options & SSL_OP_NO_SSLv3))
+				return s->version == SSL3_VERSION;
+			if (!(s->options & SSL_OP_NO_SSLv2))
+				return s->version == SSL2_VERSION;
+			}
+		return 0; /* Unexpected state; fail closed. */
+
 	default:
 		break;
 		}
@@ -2274,6 +2297,7 @@
 		break;
 
 #endif
+
 	default:
 		return(0);
 		}

Modified: trunk/crypto/openssl/ssl/s3_pkt.c
===================================================================
--- trunk/crypto/openssl/ssl/s3_pkt.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/ssl/s3_pkt.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -229,6 +229,12 @@
 	return(n);
 	}
 
+/* MAX_EMPTY_RECORDS defines the number of consecutive, empty records that will
+ * be processed per call to ssl3_get_record. Without this limit an attacker
+ * could send empty records at a faster rate than we can process and cause
+ * ssl3_get_record to loop forever. */
+#define MAX_EMPTY_RECORDS 32
+
 /* Call this to get a new input record.
  * It will return <= 0 if more data is needed, normally due to an error
  * or non-blocking IO.
@@ -249,6 +255,7 @@
 	short version;
 	unsigned mac_size, orig_len;
 	size_t extra;
+	unsigned empty_record_count = 0;
 
 	rr= &(s->s3->rrec);
 	sess=s->session;
@@ -476,7 +483,17 @@
 	s->packet_length=0;
 
 	/* just read a 0 length packet */
-	if (rr->length == 0) goto again;
+	if (rr->length == 0)
+		{
+		empty_record_count++;
+		if (empty_record_count > MAX_EMPTY_RECORDS)
+			{
+			al=SSL_AD_UNEXPECTED_MESSAGE;
+			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_RECORD_TOO_SMALL);
+			goto f_err;
+			}
+		goto again;
+		}
 
 	return(1);
 

Modified: trunk/crypto/openssl/ssl/s3_srvr.c
===================================================================
--- trunk/crypto/openssl/ssl/s3_srvr.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/ssl/s3_srvr.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -128,6 +128,7 @@
 #include <stdio.h>
 #include "ssl_locl.h"
 #include "kssl_lcl.h"
+#include "../crypto/constant_time_locl.h"
 #include <openssl/buffer.h>
 #include <openssl/rand.h>
 #include <openssl/objects.h>
@@ -1828,6 +1829,10 @@
 #ifndef OPENSSL_NO_RSA
 	if (l & SSL_kRSA)
 		{
+		unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH];
+		int decrypt_len;
+		unsigned char decrypt_good, version_good;
+
 		/* FIX THIS UP EAY EAY EAY EAY */
 		if (s->s3->tmp.use_rsa_tmp)
 			{
@@ -1876,54 +1881,61 @@
 				n=i;
 			}
 
-		i=RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);
+		/* We must not leak whether a decryption failure occurs because
+		 * of Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see
+		 * RFC 2246, section 7.4.7.1). The code follows that advice of
+		 * the TLS RFC and generates a random premaster secret for the
+		 * case that the decrypt fails. See
+		 * https://tools.ietf.org/html/rfc5246#section-7.4.7.1 */
 
-		al = -1;
-		
-		if (i != SSL_MAX_MASTER_KEY_LENGTH)
+		/* should be RAND_bytes, but we cannot work around a failure. */
+		if (RAND_pseudo_bytes(rand_premaster_secret,
+				      sizeof(rand_premaster_secret)) <= 0)
+			goto err;
+		decrypt_len = RSA_private_decrypt((int)n,p,p,rsa,RSA_PKCS1_PADDING);
+		ERR_clear_error();
+
+		/* decrypt_len should be SSL_MAX_MASTER_KEY_LENGTH.
+		 * decrypt_good will be 0xff if so and zero otherwise. */
+		decrypt_good = constant_time_eq_int_8(decrypt_len, SSL_MAX_MASTER_KEY_LENGTH);
+
+		/* If the version in the decrypted pre-master secret is correct
+		 * then version_good will be 0xff, otherwise it'll be zero.
+		 * The Klima-Pokorny-Rosa extension of Bleichenbacher's attack
+		 * (http://eprint.iacr.org/2003/052/) exploits the version
+		 * number check as a "bad version oracle". Thus version checks
+		 * are done in constant time and are treated like any other
+		 * decryption error. */
+		version_good = constant_time_eq_8(p[0], (unsigned)(s->client_version>>8));
+		version_good &= constant_time_eq_8(p[1], (unsigned)(s->client_version&0xff));
+
+		/* The premaster secret must contain the same version number as
+		 * the ClientHello to detect version rollback attacks
+		 * (strangely, the protocol does not offer such protection for
+		 * DH ciphersuites). However, buggy clients exist that send the
+		 * negotiated protocol version instead if the server does not
+		 * support the requested protocol version. If
+		 * SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. */
+		if (s->options & SSL_OP_TLS_ROLLBACK_BUG)
 			{
-			al=SSL_AD_DECODE_ERROR;
-			/* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); */
+			unsigned char workaround_good;
+			workaround_good = constant_time_eq_8(p[0], (unsigned)(s->version>>8));
+			workaround_good &= constant_time_eq_8(p[1], (unsigned)(s->version&0xff));
+			version_good |= workaround_good;
 			}
 
-		if ((al == -1) && !((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff))))
+		/* Both decryption and version must be good for decrypt_good
+		 * to remain non-zero (0xff). */
+		decrypt_good &= version_good;
+
+		/* Now copy rand_premaster_secret over p using
+		 * decrypt_good_mask. */
+		for (i = 0; i < (int) sizeof(rand_premaster_secret); i++)
 			{
-			/* The premaster secret must contain the same version number as the
-			 * ClientHello to detect version rollback attacks (strangely, the
-			 * protocol does not offer such protection for DH ciphersuites).
-			 * However, buggy clients exist that send the negotiated protocol
-			 * version instead if the server does not support the requested
-			 * protocol version.
-			 * If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. */
-			if (!((s->options & SSL_OP_TLS_ROLLBACK_BUG) &&
-				(p[0] == (s->version>>8)) && (p[1] == (s->version & 0xff))))
-				{
-				al=SSL_AD_DECODE_ERROR;
-				/* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_PROTOCOL_VERSION_NUMBER); */
-
-				/* The Klima-Pokorny-Rosa extension of Bleichenbacher's attack
-				 * (http://eprint.iacr.org/2003/052/) exploits the version
-				 * number check as a "bad version oracle" -- an alert would
-				 * reveal that the plaintext corresponding to some ciphertext
-				 * made up by the adversary is properly formatted except
-				 * that the version number is wrong.  To avoid such attacks,
-				 * we should treat this just like any other decryption error. */
-				}
+			p[i] = constant_time_select_8(decrypt_good, p[i],
+						      rand_premaster_secret[i]);
 			}
 
-		if (al != -1)
-			{
-			/* Some decryption failure -- use random value instead as countermeasure
-			 * against Bleichenbacher's attack on PKCS #1 v1.5 RSA padding
-			 * (see RFC 2246, section 7.4.7.1). */
-			ERR_clear_error();
-			i = SSL_MAX_MASTER_KEY_LENGTH;
-			p[0] = s->client_version >> 8;
-			p[1] = s->client_version & 0xff;
-			if (RAND_pseudo_bytes(p+2, i-2) <= 0) /* should be RAND_bytes, but we cannot work around a failure */
-				goto err;
-			}
-	
 		s->session->master_key_length=
 			s->method->ssl3_enc->generate_master_secret(s,
 				s->session->master_key,

Modified: trunk/crypto/openssl/ssl/ssl.h
===================================================================
--- trunk/crypto/openssl/ssl/ssl.h	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/ssl/ssl.h	2014-10-28 11:53:50 UTC (rev 6897)
@@ -563,6 +563,10 @@
 #define SSL_MODE_AUTO_RETRY 0x00000004L
 /* Don't attempt to automatically build certificate chain */
 #define SSL_MODE_NO_AUTO_CHAIN 0x00000008L
+/* Send TLS_FALLBACK_SCSV in the ClientHello.
+ * To be set by applications that reconnect with a downgraded protocol
+ * version; see draft-ietf-tls-downgrade-scsv-00 for details. */
+#define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080L
 
 
 /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
@@ -1209,6 +1213,7 @@
 #define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
 #define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
 #define SSL_AD_UNKNOWN_PSK_IDENTITY	TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */
+#define SSL_AD_INAPPROPRIATE_FALLBACK	TLS1_AD_INAPPROPRIATE_FALLBACK /* fatal */
 
 #define SSL_ERROR_NONE			0
 #define SSL_ERROR_SSL			1
@@ -1298,6 +1303,8 @@
 #define SSL_CTRL_CLEAR_OPTIONS			77
 #define SSL_CTRL_CLEAR_MODE			78
 
+#define SSL_CTRL_CHECK_PROTO_VERSION		119
+
 #define DTLSv1_get_timeout(ssl, arg) \
 	SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
 #define DTLSv1_handle_timeout(ssl) \
@@ -1945,6 +1952,7 @@
 #define SSL_R_HTTPS_PROXY_REQUEST			 155
 #define SSL_R_HTTP_REQUEST				 156
 #define SSL_R_ILLEGAL_PADDING				 283
+#define SSL_R_INAPPROPRIATE_FALLBACK			 373
 #define SSL_R_INVALID_CHALLENGE_LENGTH			 158
 #define SSL_R_INVALID_COMMAND				 280
 #define SSL_R_INVALID_PURPOSE				 278
@@ -2072,6 +2080,7 @@
 #define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED		 1021
 #define SSL_R_TLSV1_ALERT_DECRYPT_ERROR			 1051
 #define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION		 1060
+#define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK	 1086
 #define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY		 1071
 #define SSL_R_TLSV1_ALERT_INTERNAL_ERROR		 1080
 #define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION		 1100

Modified: trunk/crypto/openssl/ssl/ssl3.h
===================================================================
--- trunk/crypto/openssl/ssl/ssl3.h	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/ssl/ssl3.h	2014-10-28 11:53:50 UTC (rev 6897)
@@ -129,9 +129,14 @@
 extern "C" {
 #endif
 
-/* Signalling cipher suite value: from draft-ietf-tls-renegotiation-03.txt */
+/* Signalling cipher suite value from RFC 5746
+ * (TLS_EMPTY_RENEGOTIATION_INFO_SCSV) */
 #define SSL3_CK_SCSV				0x030000FF
 
+/* Signalling cipher suite value from draft-ietf-tls-downgrade-scsv-00
+ * (TLS_FALLBACK_SCSV) */
+#define SSL3_CK_FALLBACK_SCSV			0x03005600
+
 #define SSL3_CK_RSA_NULL_MD5			0x03000001
 #define SSL3_CK_RSA_NULL_SHA			0x03000002
 #define SSL3_CK_RSA_RC4_40_MD5 			0x03000003

Modified: trunk/crypto/openssl/ssl/ssl_err.c
===================================================================
--- trunk/crypto/openssl/ssl/ssl_err.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/ssl/ssl_err.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -341,6 +341,7 @@
 {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST)   ,"https proxy request"},
 {ERR_REASON(SSL_R_HTTP_REQUEST)          ,"http request"},
 {ERR_REASON(SSL_R_ILLEGAL_PADDING)       ,"illegal padding"},
+{ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK),"inappropriate fallback"},
 {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH),"invalid challenge length"},
 {ERR_REASON(SSL_R_INVALID_COMMAND)       ,"invalid command"},
 {ERR_REASON(SSL_R_INVALID_PURPOSE)       ,"invalid purpose"},
@@ -468,6 +469,7 @@
 {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED),"tlsv1 alert decryption failed"},
 {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR),"tlsv1 alert decrypt error"},
 {ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION),"tlsv1 alert export restriction"},
+{ERR_REASON(SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK),"tlsv1 alert inappropriate fallback"},
 {ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY),"tlsv1 alert insufficient security"},
 {ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR),"tlsv1 alert internal error"},
 {ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION),"tlsv1 alert no renegotiation"},

Modified: trunk/crypto/openssl/ssl/ssl_lib.c
===================================================================
--- trunk/crypto/openssl/ssl/ssl_lib.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/ssl/ssl_lib.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -1296,6 +1296,8 @@
 
 	if (sk == NULL) return(0);
 	q=p;
+	if (put_cb == NULL)
+		put_cb = s->method->put_cipher_by_char;
 
 	for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
 		{
@@ -1305,25 +1307,37 @@
                     continue;
 #endif /* OPENSSL_NO_KRB5 */                    
 
-		j = put_cb ? put_cb(c,p) : ssl_put_cipher_by_char(s,c,p);
+		j = put_cb(c,p);
 		p+=j;
 		}
-	/* If p == q, no ciphers and caller indicates an error. Otherwise
-	 * add SCSV if not renegotiating.
-	 */
-	if (p != q && !s->new_session)
+	/* If p == q, no ciphers; caller indicates an error.
+	 * Otherwise, add applicable SCSVs. */
+	if (p != q)
 		{
-		static SSL_CIPHER scsv =
+		if (!s->new_session)
 			{
-			0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0,
-			};
-		j = put_cb ? put_cb(&scsv,p) : ssl_put_cipher_by_char(s,&scsv,p);
-		p+=j;
+			static SSL_CIPHER scsv =
+				{
+				0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0,
+				};
+			j = put_cb(&scsv,p);
+			p+=j;
 #ifdef OPENSSL_RI_DEBUG
-		fprintf(stderr, "SCSV sent by client\n");
+			fprintf(stderr, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV sent by client\n");
 #endif
-		}
+			}
 
+		if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV)
+			{
+			static SSL_CIPHER scsv =
+				{
+				0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0,
+				};
+			j = put_cb(&scsv,p);
+			p+=j;
+			}
+ 		}
+
 	return(p-q);
 	}
 
@@ -1333,11 +1347,12 @@
 	SSL_CIPHER *c;
 	STACK_OF(SSL_CIPHER) *sk;
 	int i,n;
+
 	if (s->s3)
 		s->s3->send_connection_binding = 0;
 
 	n=ssl_put_cipher_by_char(s,NULL,NULL);
-	if ((num%n) != 0)
+	if (n == 0 || (num%n) != 0)
 		{
 		SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
 		return(NULL);
@@ -1352,7 +1367,7 @@
 
 	for (i=0; i<num; i+=n)
 		{
-		/* Check for SCSV */
+		/* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
 		if (s->s3 && (n != 3 || !p[0]) &&
 			(p[n-2] == ((SSL3_CK_SCSV >> 8) & 0xff)) &&
 			(p[n-1] == (SSL3_CK_SCSV & 0xff)))
@@ -1372,6 +1387,23 @@
 			continue;
 			}
 
+		/* Check for TLS_FALLBACK_SCSV */
+		if ((n != 3 || !p[0]) &&
+			(p[n-2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) &&
+			(p[n-1] == (SSL3_CK_FALLBACK_SCSV & 0xff)))
+			{
+			/* The SCSV indicates that the client previously tried a higher version.
+			 * Fail if the current version is an unexpected downgrade. */
+			if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL))
+				{
+				SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,SSL_R_INAPPROPRIATE_FALLBACK);
+				if (s->s3)
+					ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INAPPROPRIATE_FALLBACK);
+				goto err;
+				}
+			continue;
+			}
+
 		c=ssl_get_cipher_by_char(s,p);
 		p+=n;
 		if (c != NULL)

Modified: trunk/crypto/openssl/ssl/t1_enc.c
===================================================================
--- trunk/crypto/openssl/ssl/t1_enc.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/ssl/t1_enc.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -855,6 +855,7 @@
 	case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE);
 	case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE);
 	case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
+	case SSL_AD_INAPPROPRIATE_FALLBACK:return(TLS1_AD_INAPPROPRIATE_FALLBACK);
 #ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
 	case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return 
 					  (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
@@ -862,4 +863,3 @@
 	default:			return(-1);
 		}
 	}
-

Modified: trunk/crypto/openssl/ssl/t1_lib.c
===================================================================
--- trunk/crypto/openssl/ssl/t1_lib.c	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/ssl/t1_lib.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -1101,7 +1101,10 @@
 	HMAC_Final(&hctx, tick_hmac, NULL);
 	HMAC_CTX_cleanup(&hctx);
 	if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen))
+		{
+		EVP_CIPHER_CTX_cleanup(&ctx);
 		goto tickerr;
+		}
 	/* Attempt to decrypt session data */
 	/* Move p after IV to start of encrypted ticket, update length */
 	p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);

Modified: trunk/crypto/openssl/ssl/tls1.h
===================================================================
--- trunk/crypto/openssl/ssl/tls1.h	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/ssl/tls1.h	2014-10-28 11:53:50 UTC (rev 6897)
@@ -80,17 +80,24 @@
 
 #define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES	0
 
+#define TLS1_VERSION			0x0301
+#define TLS1_1_VERSION			0x0302
 #define TLS1_2_VERSION			0x0303
-#define TLS1_2_VERSION_MAJOR		0x03
-#define TLS1_2_VERSION_MINOR		0x03
+/* TLS 1.1 and 1.2 are not supported by this version of OpenSSL, so
+ * TLS_MAX_VERSION indicates TLS 1.0 regardless of the above
+ * definitions. (s23_clnt.c and s23_srvr.c have an OPENSSL_assert()
+ * check that would catch the error if TLS_MAX_VERSION was too low.)
+ */
+#define TLS_MAX_VERSION			TLS1_VERSION
 
-#define TLS1_1_VERSION			0x0302
+#define TLS1_VERSION_MAJOR		0x03
+#define TLS1_VERSION_MINOR		0x01
+
 #define TLS1_1_VERSION_MAJOR		0x03
 #define TLS1_1_VERSION_MINOR		0x02
 
-#define TLS1_VERSION			0x0301
-#define TLS1_VERSION_MAJOR		0x03
-#define TLS1_VERSION_MINOR		0x01
+#define TLS1_2_VERSION_MAJOR		0x03
+#define TLS1_2_VERSION_MINOR		0x03
 
 #define TLS1_get_version(s) \
 		((s->version >> 8) == TLS1_VERSION_MAJOR ? s->version : 0)
@@ -108,6 +115,7 @@
 #define TLS1_AD_PROTOCOL_VERSION	70	/* fatal */
 #define TLS1_AD_INSUFFICIENT_SECURITY	71	/* fatal */
 #define TLS1_AD_INTERNAL_ERROR		80	/* fatal */
+#define TLS1_AD_INAPPROPRIATE_FALLBACK	86	/* fatal */
 #define TLS1_AD_USER_CANCELLED		90
 #define TLS1_AD_NO_RENEGOTIATION	100
 /* codes 110-114 are from RFC3546 */
@@ -419,6 +427,3 @@
 }
 #endif
 #endif
-
-
-

Modified: trunk/crypto/openssl/test/Makefile
===================================================================
--- trunk/crypto/openssl/test/Makefile	2014-10-28 11:52:31 UTC (rev 6896)
+++ trunk/crypto/openssl/test/Makefile	2014-10-28 11:53:50 UTC (rev 6897)
@@ -72,6 +72,7 @@
 FIPS_DSSVS=	fips_dssvs
 FIPS_RNGVS=	fips_rngvs
 FIPS_TEST_SUITE=fips_test_suite
+CONSTTIMETEST=  constant_time_test
 
 TESTS=		alltests
 
@@ -88,7 +89,8 @@
 	$(FIPS_HMACTEST)$(EXE_EXT) $(FIPS_RSAVTEST)$(EXE_EXT) \
 	$(FIPS_RSASTEST)$(EXE_EXT) $(FIPS_RSAGTEST)$(EXE_EXT) \
 	$(FIPS_DSSVS)$(EXE_EXT) $(FIPS_DSATEST)$(EXE_EXT) \
-	$(FIPS_RNGVS)$(EXE_EXT) $(FIPS_TEST_SUITE)$(EXE_EXT) jpaketest$(EXE_EXT)
+	$(FIPS_RNGVS)$(EXE_EXT) $(FIPS_TEST_SUITE)$(EXE_EXT) \
+	jpaketest$(EXE_EXT) $(CONSTTIMETEST)$(EXE_EXT)
 
 # $(METHTEST)$(EXE_EXT)
 
@@ -105,7 +107,7 @@
 	$(FIPS_AESTEST).o $(FIPS_HMACTEST).o $(FIPS_RSAVTEST).o \
 	$(FIPS_RSASTEST).o $(FIPS_RSAGTEST).o \
 	$(FIPS_DSSVS).o $(FIPS_DSATEST).o $(FIPS_RNGVS).o $(FIPS_TEST_SUITE).o \
-	jpaketest.o
+	jpaketest.o $(CONSTTIMETEST).o
 
 SRC=	$(BNTEST).c $(ECTEST).c  $(ECDSATEST).c $(ECDHTEST).c $(IDEATEST).c \
 	$(MD2TEST).c  $(MD4TEST).c $(MD5TEST).c \
@@ -119,7 +121,7 @@
 	$(FIPS_AESTEST).c $(FIPS_HMACTEST).c $(FIPS_RSAVTEST).c \
 	$(FIPS_RSASTEST).c $(FIPS_RSAGTEST).c \
 	$(FIPS_DSSVS).c $(FIPS_DSATEST).c $(FIPS_RNGVS).c $(FIPS_TEST_SUITE).c \
-	jpaketest.c
+	jpaketest.c $(CONSTTIMETEST).c
 
 EXHEADER= 
 HEADER=	$(EXHEADER)
@@ -161,7 +163,8 @@
 	test_rand test_bn test_ec test_ecdsa test_ecdh \
 	test_enc test_x509 test_rsa test_crl test_sid \
 	test_gen test_req test_pkcs7 test_verify test_dh test_dsa \
-	test_ss test_ca test_engine test_evp test_ssl test_ige test_jpake
+	test_ss test_ca test_engine test_evp test_ssl test_ige test_jpake \
+	test_constant_time
 
 test_evp:
 	../util/shlib_wrap.sh ./$(EVPTEST) evptests.txt
@@ -333,6 +336,10 @@
 	@echo "Test JPAKE"
 	../util/shlib_wrap.sh ./jpaketest
 
+test_constant_time: $(CONSTTIMETEST)$(EXE_EXT)
+	@echo "Test constant time utilites"
+	../util/shlib_wrap.sh ./$(CONSTTIMETEST)
+
 lint:
 	lint -DLINT $(INCLUDES) $(SRC)>fluff
 
@@ -527,6 +534,9 @@
 jpaketest$(EXE_EXT): jpaketest.o $(DLIBCRYPTO)
 	@target=jpaketest; $(BUILD_CMD)
 
+$(CONSTTIMETEST)$(EXE_EXT): $(CONSTTIMETEST).o
+	@target=$(CONSTTIMETEST) $(BUILD_CMD)
+
 #$(AESTEST).o: $(AESTEST).c
 #	$(CC) -c $(CFLAGS) -DINTERMEDIATE_VALUE_KAT -DTRACE_KAT_MCT $(AESTEST).c
 
@@ -561,6 +571,9 @@
 bntest.o: ../include/openssl/x509_vfy.h bntest.c
 casttest.o: ../e_os.h ../include/openssl/cast.h ../include/openssl/e_os2.h
 casttest.o: ../include/openssl/opensslconf.h casttest.c
+constant_time_test.o: ../crypto/constant_time_locl.h ../e_os.h
+constant_time_test.o: ../include/openssl/e_os2.h
+constant_time_test.o: ../include/openssl/opensslconf.h constant_time_test.c
 destest.o: ../include/openssl/des.h ../include/openssl/des_old.h
 destest.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
 destest.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h

Copied: trunk/crypto/openssl/test/constant_time_test.c (from rev 6896, vendor-crypto/openssl/dist/test/constant_time_test.c)
===================================================================
--- trunk/crypto/openssl/test/constant_time_test.c	                        (rev 0)
+++ trunk/crypto/openssl/test/constant_time_test.c	2014-10-28 11:53:50 UTC (rev 6897)
@@ -0,0 +1 @@
+link ../crypto/constant_time_test.c
\ No newline at end of file



More information about the Midnightbsd-cvs mailing list