openssl-1.0.1e upgrade

Change-Id: I4520a7e044b1c6a1b9d09b365bc18b178826131e
diff --git a/android.testssl/testssl b/android.testssl/testssl
index 2eda40c..5ff4860 100755
--- a/android.testssl/testssl
+++ b/android.testssl/testssl
@@ -122,6 +122,23 @@
 echo test sslv2/sslv3 with both client and server authentication via BIO pair and app verify
 $ssltest -bio_pair -server_auth -client_auth -app_verify $CA $extra || exit 1
 
+echo "Testing ciphersuites"
+for protocol in TLSv1.2 SSLv3; do
+  echo "Testing ciphersuites for $protocol"
+  for cipher in `adb shell /system/bin/openssl ciphers "RSA+$protocol" | tr ':' ' '`; do
+    echo "Testing $cipher"
+    prot=""
+    if [ $protocol = "SSLv3" ] ; then
+      prot="-ssl3"
+    fi
+    $ssltest -cipher $cipher $prot
+    if [ $? -ne 0 ] ; then
+	  echo "Failed $cipher"
+	  exit 1
+    fi
+  done
+done
+
 #############################################################################
 
 if [ `adb shell /system/bin/openssl no-dh` = no-dh ]; then
diff --git a/apps/s_client.c b/apps/s_client.c
index 3a40a3f..791e277 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -363,7 +363,9 @@
 #endif
 	BIO_printf(bio_err," -cutthrough       - enable 1-RTT full-handshake for strong ciphers\n");
 	BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
+#ifndef OPENSSL_NO_SRTP
 	BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
+#endif
  	BIO_printf(bio_err," -keymatexport label   - Export keying material using label\n");
  	BIO_printf(bio_err," -keymatexportlen len  - Export len bytes of keying material (default 20)\n");
 	}
@@ -503,7 +505,9 @@
 	}
 
 #endif
+#ifndef OPENSSL_NO_SRTP
 	char *srtp_profiles = NULL;
+#endif
 
 # ifndef OPENSSL_NO_NEXTPROTONEG
 /* This the context that we pass to next_proto_cb */
@@ -949,11 +953,13 @@
 			jpake_secret = *++argv;
 			}
 #endif
+#ifndef OPENSSL_NO_SRTP
 		else if (strcmp(*argv,"-use_srtp") == 0)
 			{
 			if (--argc < 1) goto bad;
 			srtp_profiles = *(++argv);
 			}
+#endif
 		else if (strcmp(*argv,"-keymatexport") == 0)
 			{
 			if (--argc < 1) goto bad;
@@ -1134,6 +1140,8 @@
 			BIO_printf(bio_c_out, "PSK key given or JPAKE in use, setting client callback\n");
 		SSL_CTX_set_psk_client_callback(ctx, psk_client_cb);
 		}
+#endif
+#ifndef OPENSSL_NO_SRTP
 	if (srtp_profiles != NULL)
 		SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
 #endif
@@ -2080,6 +2088,7 @@
 	}
 #endif
 
+#ifndef OPENSSL_NO_SRTP
  	{
  	SRTP_PROTECTION_PROFILE *srtp_profile=SSL_get_selected_srtp_profile(s);
  
@@ -2087,6 +2096,7 @@
 		BIO_printf(bio,"SRTP Extension negotiated, profile=%s\n",
 			   srtp_profile->name);
 	}
+#endif
  
 	SSL_SESSION_print(bio,SSL_get_session(s));
 	if (keymatexportlabel != NULL)
diff --git a/apps/s_server.c b/apps/s_server.c
index 4720c05..8198d7f 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -556,7 +556,9 @@
 # ifndef OPENSSL_NO_NEXTPROTONEG
 	BIO_printf(bio_err," -nextprotoneg arg - set the advertised protocols for the NPN extension (comma-separated list)\n");
 # endif
+# ifndef OPENSSL_NO_SRTP
         BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
+# endif
 #endif
 	BIO_printf(bio_err," -keymatexport label   - Export keying material using label\n");
 	BIO_printf(bio_err," -keymatexportlen len  - Export len bytes of keying material (default 20)\n");
@@ -923,7 +925,9 @@
 #ifndef OPENSSL_NO_SRP
 	static srpsrvparm srp_callback_parm;
 #endif
+#ifndef OPENSSL_NO_SRTP
 static char *srtp_profiles = NULL;
+#endif
 
 int MAIN(int argc, char *argv[])
 	{
@@ -1319,11 +1323,13 @@
 			jpake_secret = *(++argv);
 			}
 #endif
+#ifndef OPENSSL_NO_SRTP
 		else if (strcmp(*argv,"-use_srtp") == 0)
 			{
 			if (--argc < 1) goto bad;
 			srtp_profiles = *(++argv);
 			}
+#endif
 		else if (strcmp(*argv,"-keymatexport") == 0)
 			{
 			if (--argc < 1) goto bad;
@@ -1549,8 +1555,10 @@
 	else
 		SSL_CTX_sess_set_cache_size(ctx,128);
 
+#ifndef OPENSSL_NO_SRTP
 	if (srtp_profiles != NULL)
 		SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
+#endif
 
 #if 0
 	if (cipher == NULL) cipher=getenv("SSL_CIPHER");
@@ -2450,6 +2458,7 @@
 		BIO_printf(bio_s_out, "\n");
 		}
 #endif
+#ifndef OPENSSL_NO_SRTP
 	{
 	SRTP_PROTECTION_PROFILE *srtp_profile
 	  = SSL_get_selected_srtp_profile(con);
@@ -2458,6 +2467,7 @@
 		BIO_printf(bio_s_out,"SRTP Extension negotiated, profile=%s\n",
 			   srtp_profile->name);
 	}
+#endif
 	if (SSL_cache_hit(con)) BIO_printf(bio_s_out,"Reused session-id\n");
 	if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) &
 		TLS1_FLAGS_TLS_PADDING_BUG)
diff --git a/crypto/evp/e_aes_cbc_hmac_sha1.c b/crypto/evp/e_aes_cbc_hmac_sha1.c
index b7aff44..483e04b 100644
--- a/crypto/evp/e_aes_cbc_hmac_sha1.c
+++ b/crypto/evp/e_aes_cbc_hmac_sha1.c
@@ -244,7 +244,10 @@
 		}
 	} else {
 		union { unsigned int  u[SHA_DIGEST_LENGTH/sizeof(unsigned int)];
-			unsigned char c[SHA_DIGEST_LENGTH]; } mac;
+			unsigned char c[32+SHA_DIGEST_LENGTH]; } mac, *pmac;
+
+		/* arrange cache line alignment */
+		pmac = (void *)(((size_t)mac.c+31)&((size_t)0-32));
 
 		/* decrypt HMAC|padding at once */
 		aesni_cbc_encrypt(in,out,len,
@@ -300,17 +303,21 @@
 
 			/* but pretend as if we hashed padded payload */
 			bitlen = key->md.Nl+(inp_len<<3);	/* at most 18 bits */
+#ifdef BSWAP
+			bitlen = BSWAP(bitlen);
+#else
 			mac.c[0] = 0;
 			mac.c[1] = (unsigned char)(bitlen>>16);
 			mac.c[2] = (unsigned char)(bitlen>>8);
 			mac.c[3] = (unsigned char)bitlen;
 			bitlen = mac.u[0];
+#endif
 
-			mac.u[0]=0;
-			mac.u[1]=0;
-			mac.u[2]=0;
-			mac.u[3]=0;
-			mac.u[4]=0;
+			pmac->u[0]=0;
+			pmac->u[1]=0;
+			pmac->u[2]=0;
+			pmac->u[3]=0;
+			pmac->u[4]=0;
 
 			for (res=key->md.num, j=0;j<len;j++) {
 				size_t c = out[j];
@@ -325,11 +332,11 @@
 				data->u[SHA_LBLOCK-1] |= bitlen&mask;
 				sha1_block_data_order(&key->md,data,1);
 				mask &= 0-((j-inp_len-73)>>(sizeof(j)*8-1));
-				mac.u[0] |= key->md.h0 & mask;
-				mac.u[1] |= key->md.h1 & mask;
-				mac.u[2] |= key->md.h2 & mask;
-				mac.u[3] |= key->md.h3 & mask;
-				mac.u[4] |= key->md.h4 & mask;
+				pmac->u[0] |= key->md.h0 & mask;
+				pmac->u[1] |= key->md.h1 & mask;
+				pmac->u[2] |= key->md.h2 & mask;
+				pmac->u[3] |= key->md.h3 & mask;
+				pmac->u[4] |= key->md.h4 & mask;
 				res=0;
 			}
 
@@ -340,11 +347,11 @@
 				data->u[SHA_LBLOCK-1] |= bitlen&mask;
 				sha1_block_data_order(&key->md,data,1);
 				mask &= 0-((j-inp_len-73)>>(sizeof(j)*8-1));
-				mac.u[0] |= key->md.h0 & mask;
-				mac.u[1] |= key->md.h1 & mask;
-				mac.u[2] |= key->md.h2 & mask;
-				mac.u[3] |= key->md.h3 & mask;
-				mac.u[4] |= key->md.h4 & mask;
+				pmac->u[0] |= key->md.h0 & mask;
+				pmac->u[1] |= key->md.h1 & mask;
+				pmac->u[2] |= key->md.h2 & mask;
+				pmac->u[3] |= key->md.h3 & mask;
+				pmac->u[4] |= key->md.h4 & mask;
 
 				memset(data,0,SHA_CBLOCK);
 				j+=64;
@@ -352,32 +359,32 @@
 			data->u[SHA_LBLOCK-1] = bitlen;
 			sha1_block_data_order(&key->md,data,1);
 			mask = 0-((j-inp_len-73)>>(sizeof(j)*8-1));
-			mac.u[0] |= key->md.h0 & mask;
-			mac.u[1] |= key->md.h1 & mask;
-			mac.u[2] |= key->md.h2 & mask;
-			mac.u[3] |= key->md.h3 & mask;
-			mac.u[4] |= key->md.h4 & mask;
+			pmac->u[0] |= key->md.h0 & mask;
+			pmac->u[1] |= key->md.h1 & mask;
+			pmac->u[2] |= key->md.h2 & mask;
+			pmac->u[3] |= key->md.h3 & mask;
+			pmac->u[4] |= key->md.h4 & mask;
 
 #ifdef BSWAP
-			mac.u[0] = BSWAP(mac.u[0]);
-			mac.u[1] = BSWAP(mac.u[1]);
-			mac.u[2] = BSWAP(mac.u[2]);
-			mac.u[3] = BSWAP(mac.u[3]);
-			mac.u[4] = BSWAP(mac.u[4]);
+			pmac->u[0] = BSWAP(pmac->u[0]);
+			pmac->u[1] = BSWAP(pmac->u[1]);
+			pmac->u[2] = BSWAP(pmac->u[2]);
+			pmac->u[3] = BSWAP(pmac->u[3]);
+			pmac->u[4] = BSWAP(pmac->u[4]);
 #else
 			for (i=0;i<5;i++) {
-				res = mac.u[i];
-				mac.c[4*i+0]=(unsigned char)(res>>24);
-				mac.c[4*i+1]=(unsigned char)(res>>16);
-				mac.c[4*i+2]=(unsigned char)(res>>8);
-				mac.c[4*i+3]=(unsigned char)res;
+				res = pmac->u[i];
+				pmac->c[4*i+0]=(unsigned char)(res>>24);
+				pmac->c[4*i+1]=(unsigned char)(res>>16);
+				pmac->c[4*i+2]=(unsigned char)(res>>8);
+				pmac->c[4*i+3]=(unsigned char)res;
 			}
 #endif
 			len += SHA_DIGEST_LENGTH;
 #else
 			SHA1_Update(&key->md,out,inp_len);
 			res = key->md.num;
-			SHA1_Final(mac.c,&key->md);
+			SHA1_Final(pmac->c,&key->md);
 
 			{
 			unsigned int inp_blocks, pad_blocks;
@@ -393,8 +400,8 @@
 			}
 #endif
 			key->md = key->tail;
-			SHA1_Update(&key->md,mac.c,SHA_DIGEST_LENGTH);
-			SHA1_Final(mac.c,&key->md);
+			SHA1_Update(&key->md,pmac->c,SHA_DIGEST_LENGTH);
+			SHA1_Final(pmac->c,&key->md);
 
 			/* verify HMAC */
 			out += inp_len;
@@ -411,7 +418,7 @@
 				cmask = ((int)(j-off-SHA_DIGEST_LENGTH))>>(sizeof(int)*8-1);
 				res |= (c^pad)&~cmask;	/* ... and padding */
 				cmask &= ((int)(off-1-j))>>(sizeof(int)*8-1);
-				res |= (c^mac.c[i])&cmask;
+				res |= (c^pmac->c[i])&cmask;
 				i += 1&cmask;
 			}
 			maxpad -= SHA_DIGEST_LENGTH;
@@ -421,7 +428,7 @@
 			}
 #else
 			for (res=0,i=0;i<SHA_DIGEST_LENGTH;i++)
-				res |= out[i]^mac.c[i];
+				res |= out[i]^pmac->c[i];
 			res = 0-((0-res)>>(sizeof(res)*8-1));
 			ret &= (int)~res;
 
diff --git a/crypto/opensslv.h b/crypto/opensslv.h
index dbea4ad..5bc8e53 100644
--- a/crypto/opensslv.h
+++ b/crypto/opensslv.h
@@ -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	0x1000104fL
+#define OPENSSL_VERSION_NUMBER	0x1000105fL
 #ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1d-fips 5 Feb 2013"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1e-fips 11 Feb 2013"
 #else
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1d 5 Feb 2013"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1e 11 Feb 2013"
 #endif
 #define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
 
diff --git a/crypto/sparccpuid.S b/crypto/sparccpuid.S
index ae61f7f..0cc247e 100644
--- a/crypto/sparccpuid.S
+++ b/crypto/sparccpuid.S
@@ -235,10 +235,10 @@
 .global	_sparcv9_vis1_probe
 .align	8
 _sparcv9_vis1_probe:
-	.word	0x81b00d80	!fxor	%f0,%f0,%f0
 	add	%sp,BIAS+2,%o1
-	retl
 	.word	0xc19a5a40	!ldda	[%o1]ASI_FP16_P,%f0
+	retl
+	.word	0x81b00d80	!fxor	%f0,%f0,%f0
 .type	_sparcv9_vis1_probe,#function
 .size	_sparcv9_vis1_probe,.-_sparcv9_vis1_probe
 
diff --git a/include/openssl/opensslv.h b/include/openssl/opensslv.h
index dbea4ad..5bc8e53 100644
--- a/include/openssl/opensslv.h
+++ b/include/openssl/opensslv.h
@@ -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	0x1000104fL
+#define OPENSSL_VERSION_NUMBER	0x1000105fL
 #ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1d-fips 5 Feb 2013"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1e-fips 11 Feb 2013"
 #else
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1d 5 Feb 2013"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1e 11 Feb 2013"
 #endif
 #define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
 
diff --git a/openssl.config b/openssl.config
index e7009ea..0993911 100644
--- a/openssl.config
+++ b/openssl.config
@@ -175,10 +175,8 @@
 include/openssl/cast.h \
 include/openssl/cms.h \
 include/openssl/idea.h \
-include/openssl/md2.h \
 include/openssl/mdc2.h \
 include/openssl/seed.h \
-include/openssl/store.h \
 include/openssl/whrlpool.h \
 install.com \
 makevms.com \
diff --git a/openssl.version b/openssl.version
index 30f1cd2..b4e8cab 100644
--- a/openssl.version
+++ b/openssl.version
@@ -1 +1 @@
-OPENSSL_VERSION=1.0.1d
+OPENSSL_VERSION=1.0.1e
diff --git a/patches/channelid.patch b/patches/channelid.patch
index 03c6931..365df47 100644
--- a/patches/channelid.patch
+++ b/patches/channelid.patch
@@ -883,7 +883,7 @@
 diff -ur openssl/ssl/t1_lib.c openssl.channelid/ssl/t1_lib.c
 --- openssl/ssl/t1_lib.c	2012-08-28 16:04:21.193349647 -0400
 +++ openssl.channelid/ssl/t1_lib.c	2012-08-28 16:04:40.603618948 -0400
-@@ -649,6 +649,16 @@
+@@ -649,7 +649,17 @@
  		}
  #endif
  
@@ -897,6 +897,7 @@
 +		s2n(0,ret);
 +		}
 +
+ #ifndef OPENSSL_NO_SRTP
          if(SSL_get_srtp_profiles(s))
                  {
                  int el;
diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c
index b0302a7..0bf87be 100644
--- a/ssl/d1_pkt.c
+++ b/ssl/d1_pkt.c
@@ -410,7 +410,6 @@
 
 	/* decrypt in place in 'rr->input' */
 	rr->data=rr->input;
-	orig_len=rr->length;
 
 	enc_err = s->method->ssl3_enc->enc(s,0);
 	/* enc_err is:
@@ -442,6 +441,9 @@
 		mac_size=EVP_MD_CTX_size(s->read_hash);
 		OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
 
+		/* kludge: *_cbc_remove_padding passes padding length in rr->type */
+		orig_len = rr->length+((unsigned int)rr->type>>8);
+
 		/* orig_len is the length of the record before any padding was
 		 * removed. This is public information, as is the MAC in use,
 		 * therefore we can safely process the record in a different
diff --git a/ssl/d1_srtp.c b/ssl/d1_srtp.c
index 928935b..ab9c419 100644
--- a/ssl/d1_srtp.c
+++ b/ssl/d1_srtp.c
@@ -115,11 +115,12 @@
   Copyright (C) 2011, RTFM, Inc.
 */
 
-#ifndef OPENSSL_NO_SRTP
-
 #include <stdio.h>
 #include <openssl/objects.h>
 #include "ssl_locl.h"
+
+#ifndef OPENSSL_NO_SRTP
+
 #include "srtp.h"
 
 
diff --git a/ssl/s3_cbc.c b/ssl/s3_cbc.c
index 3c2c165..02edf3f 100644
--- a/ssl/s3_cbc.c
+++ b/ssl/s3_cbc.c
@@ -76,6 +76,13 @@
 #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)
 	{
@@ -84,7 +91,7 @@
 	}
 
 /* constant_time_eq_8 returns 0xff if a==b and 0x00 otherwise. */
-static unsigned char constant_time_eq_8(unsigned char a, unsigned char b)
+static unsigned char constant_time_eq_8(unsigned a, unsigned b)
 	{
 	unsigned c = a ^ b;
 	c--;
@@ -139,31 +146,22 @@
 			    unsigned mac_size)
 	{
 	unsigned padding_length, good, to_check, i;
-	const char has_explicit_iv =
-		s->version >= TLS1_1_VERSION || s->version == DTLS1_VERSION;
-	const unsigned overhead = 1 /* padding length byte */ +
-				  mac_size +
-				  (has_explicit_iv ? block_size : 0);
-
-	/* These lengths are all public so we can test them in non-constant
-	 * time. */
-	if (overhead > rec->length)
-		return 0;
-
-	/* We can always safely skip the explicit IV. We check at the beginning
-	 * of this function that the record has at least enough space for the
-	 * IV, MAC and padding length byte. (These can be checked in
-	 * non-constant time because it's all public information.) So, if the
-	 * padding was invalid, then we didn't change |rec->length| and this is
-	 * safe. If the padding was valid then we know that we have at least
-	 * overhead+padding_length bytes of space and so this is still safe
-	 * because overhead accounts for the explicit IV. */
-	if (has_explicit_iv)
+	const unsigned overhead = 1 /* padding length byte */ + mac_size;
+	/* Check if version requires explicit IV */
+	if (s->version >= TLS1_1_VERSION || s->version == DTLS1_VERSION)
 		{
+		/* These lengths are all public so we can test them in
+		 * non-constant time.
+		 */
+		if (overhead + block_size > rec->length)
+			return 0;
+		/* We can now safely skip explicit IV */
 		rec->data += block_size;
 		rec->input += block_size;
 		rec->length -= block_size;
 		}
+	else if (overhead > rec->length)
+		return 0;
 
 	padding_length = rec->data[rec->length-1];
 
@@ -190,7 +188,7 @@
 	if (EVP_CIPHER_flags(s->enc_read_ctx->cipher)&EVP_CIPH_FLAG_AEAD_CIPHER)
 		{
 		/* padding is already verified */
-		rec->length -= padding_length;
+		rec->length -= padding_length + 1;
 		return 1;
 		}
 
@@ -234,10 +232,6 @@
 	return (int)((good & 1) | (~good & -1));
 	}
 
-#if defined(_M_AMD64) || defined(__x86_64__)
-#define CBC_MAC_ROTATE_IN_PLACE
-#endif
-
 /* ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in
  * constant time (independent of the concrete value of rec->length, which may
  * vary within a 256-byte window).
@@ -251,15 +245,18 @@
  *
  * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with
  * variable accesses in a 64-byte-aligned buffer. Assuming that this fits into
- * a single cache-line, then the variable memory accesses don't actually affect
- * the timing. This has been tested to be true on Intel amd64 chips.
+ * a single or pair of cache-lines, then the variable memory accesses don't
+ * actually affect the timing. CPUs with smaller cache-lines [if any] are
+ * not multi-core and are not considered vulnerable to cache-timing attacks.
  */
+#define CBC_MAC_ROTATE_IN_PLACE
+
 void ssl3_cbc_copy_mac(unsigned char* out,
 		       const SSL3_RECORD *rec,
 		       unsigned md_size,unsigned orig_len)
 	{
 #if defined(CBC_MAC_ROTATE_IN_PLACE)
-	unsigned char rotated_mac_buf[EVP_MAX_MD_SIZE*2];
+	unsigned char rotated_mac_buf[64+EVP_MAX_MD_SIZE];
 	unsigned char *rotated_mac;
 #else
 	unsigned char rotated_mac[EVP_MAX_MD_SIZE];
@@ -279,7 +276,7 @@
 	OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE);
 
 #if defined(CBC_MAC_ROTATE_IN_PLACE)
-	rotated_mac = (unsigned char*) (((intptr_t)(rotated_mac_buf + 64)) & ~63);
+	rotated_mac = rotated_mac_buf + ((0-(size_t)rotated_mac_buf)&63);
 #endif
 
 	/* This information is public so it's safe to branch based on it. */
@@ -297,16 +294,13 @@
 	rotate_offset = (div_spoiler + mac_start - scan_start) % md_size;
 
 	memset(rotated_mac, 0, md_size);
-	for (i = scan_start; i < orig_len;)
+	for (i = scan_start, j = 0; i < orig_len; i++)
 		{
-		for (j = 0; j < md_size && i < orig_len; i++, j++)
-			{
-			unsigned char mac_started = constant_time_ge(i, mac_start);
-			unsigned char mac_ended = constant_time_ge(i, mac_end);
-			unsigned char b = 0;
-			b = rec->data[i];
-			rotated_mac[j] |= b & mac_started & ~mac_ended;
-			}
+		unsigned char mac_started = constant_time_ge(i, mac_start);
+		unsigned char mac_ended = constant_time_ge(i, mac_end);
+		unsigned char b = rec->data[i];
+		rotated_mac[j++] |= b & mac_started & ~mac_ended;
+		j &= constant_time_lt(j,md_size);
 		}
 
 	/* Now rotate the MAC */
@@ -314,30 +308,43 @@
 	j = 0;
 	for (i = 0; i < md_size; i++)
 		{
-		unsigned char offset = (div_spoiler + rotate_offset + i) % md_size;
-		out[j++] = rotated_mac[offset];
+		/* in case cache-line is 32 bytes, touch second line */
+		((volatile unsigned char *)rotated_mac)[rotate_offset^32];
+		out[j++] = rotated_mac[rotate_offset++];
+		rotate_offset &= constant_time_lt(rotate_offset,md_size);
 		}
 #else
 	memset(out, 0, md_size);
+	rotate_offset = md_size - rotate_offset;
+	rotate_offset &= constant_time_lt(rotate_offset,md_size);
 	for (i = 0; i < md_size; i++)
 		{
-		unsigned char offset = (div_spoiler + md_size - rotate_offset + i) % md_size;
 		for (j = 0; j < md_size; j++)
-			out[j] |= rotated_mac[i] & constant_time_eq_8(j, offset);
+			out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset);
+		rotate_offset++;
+		rotate_offset &= constant_time_lt(rotate_offset,md_size);
 		}
 #endif
 	}
 
+/* u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in
+ * little-endian order. The value of p is advanced by four. */
+#define u32toLE(n, p) \
+	(*((p)++)=(unsigned char)(n), \
+	 *((p)++)=(unsigned char)(n>>8), \
+	 *((p)++)=(unsigned char)(n>>16), \
+	 *((p)++)=(unsigned char)(n>>24))
+
 /* These functions serialize the state of a hash and thus perform the standard
  * "final" operation without adding the padding and length that such a function
  * typically does. */
 static void tls1_md5_final_raw(void* ctx, unsigned char *md_out)
 	{
 	MD5_CTX *md5 = ctx;
-	l2n(md5->A, md_out);
-	l2n(md5->B, md_out);
-	l2n(md5->C, md_out);
-	l2n(md5->D, md_out);
+	u32toLE(md5->A, md_out);
+	u32toLE(md5->B, md_out);
+	u32toLE(md5->C, md_out);
+	u32toLE(md5->D, md_out);
 	}
 
 static void tls1_sha1_final_raw(void* ctx, unsigned char *md_out)
@@ -457,6 +464,7 @@
 	/* mdLengthSize is the number of bytes in the length field that terminates
 	* the hash. */
 	unsigned md_length_size = 8;
+	char length_is_big_endian = 1;
 
 	/* This is a, hopefully redundant, check that allows us to forget about
 	 * many possible overflows later in this function. */
@@ -470,6 +478,7 @@
 			md_transform = (void(*)(void *ctx, const unsigned char *block)) MD5_Transform;
 			md_size = 16;
 			sslv3_pad_length = 48;
+			length_is_big_endian = 0;
 			break;
 		case NID_sha1:
 			SHA1_Init((SHA_CTX*)md_state.c);
@@ -610,11 +619,22 @@
 		md_transform(md_state.c, hmac_pad);
 		}
 
-	memset(length_bytes,0,md_length_size-4);
-	length_bytes[md_length_size-4] = (unsigned char)(bits>>24);
-	length_bytes[md_length_size-3] = (unsigned char)(bits>>16);
-	length_bytes[md_length_size-2] = (unsigned char)(bits>>8);
-	length_bytes[md_length_size-1] = (unsigned char)bits;
+	if (length_is_big_endian)
+		{
+		memset(length_bytes,0,md_length_size-4);
+		length_bytes[md_length_size-4] = (unsigned char)(bits>>24);
+		length_bytes[md_length_size-3] = (unsigned char)(bits>>16);
+		length_bytes[md_length_size-2] = (unsigned char)(bits>>8);
+		length_bytes[md_length_size-1] = (unsigned char)bits;
+		}
+	else
+		{
+		memset(length_bytes,0,md_length_size);
+		length_bytes[md_length_size-5] = (unsigned char)(bits>>24);
+		length_bytes[md_length_size-6] = (unsigned char)(bits>>16);
+		length_bytes[md_length_size-7] = (unsigned char)(bits>>8);
+		length_bytes[md_length_size-8] = (unsigned char)bits;
+		}
 
 	if (k > 0)
 		{
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index a5d646a..3b7e3b5 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -1064,7 +1064,10 @@
 	 * client authentication.
 	 */
 	if (TLS1_get_version(s) < TLS1_2_VERSION && !ssl3_digest_cached_records(s))
+		{
+		al = SSL_AD_INTERNAL_ERROR;
 		goto f_err;
+		}
 	/* lets get the compression algorithm */
 	/* COMPRESSION */
 #ifdef OPENSSL_NO_COMP
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index bf8da98..804291e 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -398,7 +398,6 @@
 
 	/* decrypt in place in 'rr->input' */
 	rr->data=rr->input;
-	orig_len=rr->length;
 
 	enc_err = s->method->ssl3_enc->enc(s,0);
 	/* enc_err is:
@@ -429,6 +428,9 @@
 		mac_size=EVP_MD_CTX_size(s->read_hash);
 		OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
 
+		/* kludge: *_cbc_remove_padding passes padding length in rr->type */
+		orig_len = rr->length+((unsigned int)rr->type>>8);
+
 		/* orig_len is the length of the record before any padding was
 		 * removed. This is public information, as is the MAC in use,
 		 * therefore we can safely process the record in a different
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index da1c2e8..5c3343a 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -1415,7 +1415,10 @@
 	if (TLS1_get_version(s) < TLS1_2_VERSION || !(s->verify_mode & SSL_VERIFY_PEER))
 		{
 		if (!ssl3_digest_cached_records(s))
+			{
+			al = SSL_AD_INTERNAL_ERROR;
 			goto f_err;
+			}
 		}
 	
 	/* we now have the following setup. 
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index c94ff26..65b2ef8 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -600,8 +600,10 @@
 		OPENSSL_free(s->next_proto_negotiated);
 #endif
 
+#ifndef OPENSSL_NO_SRTP
         if (s->srtp_profiles)
             sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
+#endif
 
 	OPENSSL_free(s);
 	}
@@ -1981,8 +1983,10 @@
 	a->comp_methods = NULL;
 #endif
 
+#ifndef OPENSSL_NO_SRTP
         if (a->srtp_profiles)
                 sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles);
+#endif
 
 #ifndef OPENSSL_NO_PSK
 	if (a->psk_identity_hint)
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 90a88ce..28d45b3 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -659,6 +659,7 @@
 		s2n(0,ret);
 		}
 
+#ifndef OPENSSL_NO_SRTP
         if(SSL_get_srtp_profiles(s))
                 {
                 int el;
@@ -677,6 +678,7 @@
 			}
                 ret += el;
                 }
+#endif
 
 	if ((extdatalen = ret-p-2)== 0) 
 		return p;
@@ -791,6 +793,7 @@
 		}
 #endif
 
+#ifndef OPENSSL_NO_SRTP
         if(s->srtp_profile)
                 {
                 int el;
@@ -809,6 +812,7 @@
 			}
                 ret+=el;
                 }
+#endif
 
 	if (((s->s3->tmp.new_cipher->id & 0xFFFF)==0x80 || (s->s3->tmp.new_cipher->id & 0xFFFF)==0x81) 
 		&& (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG))
@@ -1352,12 +1356,14 @@
 			s->s3->tlsext_channel_id_valid = 1;
 
 		/* session ticket processed earlier */
+#ifndef OPENSSL_NO_SRTP
 		else if (type == TLSEXT_TYPE_use_srtp)
-                        {
+			{
 			if(ssl_parse_clienthello_use_srtp_ext(s, data, size,
 							      al))
 				return 0;
-                        }
+			}
+#endif
 
 		data+=size;
 		}
@@ -1552,7 +1558,7 @@
 			unsigned char selected_len;
 
 			/* We must have requested it. */
-			if ((s->ctx->next_proto_select_cb == NULL))
+			if (s->ctx->next_proto_select_cb == NULL)
 				{
 				*al = TLS1_AD_UNSUPPORTED_EXTENSION;
 				return 0;
@@ -1605,12 +1611,14 @@
 				}
 			}
 #endif
+#ifndef OPENSSL_NO_SRTP
 		else if (type == TLSEXT_TYPE_use_srtp)
-                        {
+			{
                         if(ssl_parse_serverhello_use_srtp_ext(s, data, size,
 							      al))
                                 return 0;
-                        }
+			}
+#endif
 
 		data+=size;		
 		}