openssl-1.0.1a upgrade

Bug: 6366068

Change-Id: I0b6ec75b5c2a8f082b4b0fe6db2697d24f2f9b00
diff --git a/ThirdPartyProject.prop b/ThirdPartyProject.prop
index 3898e40..68629bd 100644
--- a/ThirdPartyProject.prop
+++ b/ThirdPartyProject.prop
@@ -1,7 +1,7 @@
 # Copyright 2010 Google Inc. All Rights Reserved.
 #Fri Jul 16 10:03:09 PDT 2010
-currentVersion=1.0.1
-version=1.0.1
+currentVersion=1.0.1a
+version=1.0.1a
 isNative=true
 feedurl=http\://www.openssl.org/
 name=openssl
diff --git a/apps/s_client.c b/apps/s_client.c
index f2aacaf..dc3bb0b 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -624,13 +624,7 @@
 	SRP_ARG srp_arg = {NULL,NULL,0,0,0,1024};
 #endif
 
-#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
 	meth=SSLv23_client_method();
-#elif !defined(OPENSSL_NO_SSL3)
-	meth=SSLv3_client_method();
-#elif !defined(OPENSSL_NO_SSL2)
-	meth=SSLv2_client_method();
-#endif
 
 	apps_startup();
 	c_Pause=0;
diff --git a/apps/s_server.c b/apps/s_server.c
index fe29b4c..3f9b370 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -969,17 +969,7 @@
 	char *srpuserseed = NULL;
 	char *srp_verifier_file = NULL;
 #endif
-#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
 	meth=SSLv23_server_method();
-#elif !defined(OPENSSL_NO_SSL3)
-	meth=SSLv3_server_method();
-#elif !defined(OPENSSL_NO_SSL2)
-	meth=SSLv2_server_method();
-#elif !defined(OPENSSL_NO_TLS1)
-	meth=TLSv1_server_method();
-#else
-  /*  #error no SSL version enabled */
-#endif
 
 	local_argc=argc;
 	local_argv=argv;
diff --git a/crypto/aes/asm/aes-armv4.pl b/crypto/aes/asm/aes-armv4.pl
index 943ce45..86b86c4 100644
--- a/crypto/aes/asm/aes-armv4.pl
+++ b/crypto/aes/asm/aes-armv4.pl
@@ -408,6 +408,7 @@
 .type   private_AES_set_encrypt_key,%function
 .align	5
 private_AES_set_encrypt_key:
+_armv4_AES_set_encrypt_key:
 	sub	r3,pc,#8		@ AES_set_encrypt_key
 	teq	r0,#0
 	moveq	r0,#-1
@@ -425,7 +426,7 @@
 	bne	.Labrt
 
 .Lok:	stmdb   sp!,{r4-r12,lr}
-	sub	$tbl,r3,#private_AES_set_encrypt_key-AES_Te-1024	@ Te4
+	sub	$tbl,r3,#_armv4_AES_set_encrypt_key-AES_Te-1024	@ Te4
 
 	mov	$rounds,r0		@ inp
 	mov	lr,r1			@ bits
@@ -685,7 +686,7 @@
 .align	5
 private_AES_set_decrypt_key:
 	str	lr,[sp,#-4]!            @ push lr
-	bl	private_AES_set_encrypt_key
+	bl	_armv4_AES_set_encrypt_key
 	teq	r0,#0
 	ldrne	lr,[sp],#4              @ pop lr
 	bne	.Labrt
diff --git a/crypto/aes/asm/aes-armv4.s b/crypto/aes/asm/aes-armv4.s
index e57e0d0..2697d4c 100644
--- a/crypto/aes/asm/aes-armv4.s
+++ b/crypto/aes/asm/aes-armv4.s
@@ -355,6 +355,7 @@
 .type   private_AES_set_encrypt_key,%function
 .align	5
 private_AES_set_encrypt_key:
+_armv4_AES_set_encrypt_key:
 	sub	r3,pc,#8		@ AES_set_encrypt_key
 	teq	r0,#0
 	moveq	r0,#-1
@@ -372,7 +373,7 @@
 	bne	.Labrt
 
 .Lok:	stmdb   sp!,{r4-r12,lr}
-	sub	r10,r3,#private_AES_set_encrypt_key-AES_Te-1024	@ Te4
+	sub	r10,r3,#_armv4_AES_set_encrypt_key-AES_Te-1024	@ Te4
 
 	mov	r12,r0		@ inp
 	mov	lr,r1			@ bits
@@ -632,7 +633,7 @@
 .align	5
 private_AES_set_decrypt_key:
 	str	lr,[sp,#-4]!            @ push lr
-	bl	private_AES_set_encrypt_key
+	bl	_armv4_AES_set_encrypt_key
 	teq	r0,#0
 	ldrne	lr,[sp],#4              @ pop lr
 	bne	.Labrt
diff --git a/crypto/aes/asm/aes-s390x.pl b/crypto/aes/asm/aes-s390x.pl
index f749a52..445a1e6 100644
--- a/crypto/aes/asm/aes-s390x.pl
+++ b/crypto/aes/asm/aes-s390x.pl
@@ -783,6 +783,7 @@
 .type	private_AES_set_encrypt_key,\@function
 .align	16
 private_AES_set_encrypt_key:
+_s390x_AES_set_encrypt_key:
 	lghi	$t0,0
 	cl${g}r	$inp,$t0
 	je	.Lminus1
@@ -836,7 +837,8 @@
 	je	1f
 	lg	%r1,24($inp)
 	stg	%r1,24($key)
-1:	st	$bits,236($key)	# save bits
+1:	st	$bits,236($key)	# save bits [for debugging purposes]
+	lgr	$t0,%r5
 	st	%r5,240($key)	# save km code
 	lghi	%r2,0
 	br	%r14
@@ -844,7 +846,7 @@
 $code.=<<___;
 .align	16
 .Lekey_internal:
-	stm${g}	%r6,%r13,6*$SIZE_T($sp)	# all non-volatile regs
+	stm${g}	%r4,%r13,4*$SIZE_T($sp)	# all non-volatile regs and $key
 
 	larl	$tbl,AES_Te+2048
 
@@ -904,8 +906,9 @@
 	la	$key,16($key)		# key+=4
 	la	$t3,4($t3)		# i++
 	brct	$rounds,.L128_loop
+	lghi	$t0,10
 	lghi	%r2,0
-	lm${g}	%r6,%r13,6*$SIZE_T($sp)
+	lm${g}	%r4,%r13,4*$SIZE_T($sp)
 	br	$ra
 
 .align	16
@@ -952,8 +955,9 @@
 	st	$s2,32($key)
 	st	$s3,36($key)
 	brct	$rounds,.L192_continue
+	lghi	$t0,12
 	lghi	%r2,0
-	lm${g}	%r6,%r13,6*$SIZE_T($sp)
+	lm${g}	%r4,%r13,4*$SIZE_T($sp)
 	br	$ra
 
 .align	16
@@ -1014,8 +1018,9 @@
 	st	$s2,40($key)
 	st	$s3,44($key)
 	brct	$rounds,.L256_continue
+	lghi	$t0,14
 	lghi	%r2,0
-	lm${g}	%r6,%r13,6*$SIZE_T($sp)
+	lm${g}	%r4,%r13,4*$SIZE_T($sp)
 	br	$ra
 
 .align	16
@@ -1066,34 +1071,26 @@
 .type	private_AES_set_decrypt_key,\@function
 .align	16
 private_AES_set_decrypt_key:
-	st${g}	$key,4*$SIZE_T($sp)	# I rely on AES_set_encrypt_key to
-	st${g}	$ra,14*$SIZE_T($sp)	# save non-volatile registers!
-	bras	$ra,AES_set_encrypt_key
-	l${g}	$key,4*$SIZE_T($sp)
+	#st${g}	$key,4*$SIZE_T($sp)	# I rely on AES_set_encrypt_key to
+	st${g}	$ra,14*$SIZE_T($sp)	# save non-volatile registers and $key!
+	bras	$ra,_s390x_AES_set_encrypt_key
+	#l${g}	$key,4*$SIZE_T($sp)
 	l${g}	$ra,14*$SIZE_T($sp)
 	ltgr	%r2,%r2
 	bnzr	$ra
 ___
 $code.=<<___ if (!$softonly);
-	l	$t0,240($key)
+	#l	$t0,240($key)
 	lhi	$t1,16
 	cr	$t0,$t1
 	jl	.Lgo
 	oill	$t0,0x80	# set "decrypt" bit
 	st	$t0,240($key)
 	br	$ra
-
-.align	16
-.Ldkey_internal:
-	st${g}	$key,4*$SIZE_T($sp)
-	st${g}	$ra,14*$SIZE_T($sp)
-	bras	$ra,.Lekey_internal
-	l${g}	$key,4*$SIZE_T($sp)
-	l${g}	$ra,14*$SIZE_T($sp)
 ___
 $code.=<<___;
-
-.Lgo:	llgf	$rounds,240($key)
+.align	16
+.Lgo:	lgr	$rounds,$t0	#llgf	$rounds,240($key)
 	la	$i1,0($key)
 	sllg	$i2,$rounds,4
 	la	$i2,0($i2,$key)
diff --git a/crypto/aes/asm/bsaes-x86_64.pl b/crypto/aes/asm/bsaes-x86_64.pl
index ff7e3af..c9c6312 100644
--- a/crypto/aes/asm/bsaes-x86_64.pl
+++ b/crypto/aes/asm/bsaes-x86_64.pl
@@ -65,12 +65,12 @@
 # function is:
 #
 # 		conversion	conversion/8x block
-# Core 2	410		0.37
-# Nehalem	310		0.35
-# Atom		570		0.26
+# Core 2	240		0.22
+# Nehalem	180		0.20
+# Atom		430		0.19
 #
 # The ratio values mean that 128-byte blocks will be processed
-# 21-27% slower, 256-byte blocks - 12-16%, 384-byte blocks - 8-11%,
+# 16-18% slower, 256-byte blocks - 9-10%, 384-byte blocks - 6-7%,
 # etc. Then keep in mind that input sizes not divisible by 128 are
 # *effectively* slower, especially shortest ones, e.g. consecutive
 # 144-byte blocks are processed 44% slower than one would expect,
@@ -85,6 +85,7 @@
 #
 # Core 2	11.0
 # Nehalem	9.16
+# Atom		20.9
 #
 # November 2011.
 #
@@ -754,7 +755,7 @@
 
 	movdqa	($key), @XMM[9]		# round 0 key
 	lea	0x10($key), $key
-	movdqa	0x60($const), @XMM[8]	# .LM0SR
+	movdqa	0x50($const), @XMM[8]	# .LM0SR
 	pxor	@XMM[9], @XMM[0]	# xor with round0 key
 	pxor	@XMM[9], @XMM[1]
 	 pshufb	@XMM[8], @XMM[0]
@@ -905,46 +906,82 @@
 .type	_bsaes_key_convert,\@abi-omnipotent
 .align	16
 _bsaes_key_convert:
-	lea	.LBS1(%rip), $const
+	lea	.Lmasks(%rip), $const
 	movdqu	($inp), %xmm7		# load round 0 key
-	movdqa	-0x10($const), %xmm8	# .LBS0
-	movdqa	0x00($const), %xmm9	# .LBS1
-	movdqa	0x10($const), %xmm10	# .LBS2
-	movdqa	0x40($const), %xmm13	# .LM0
-	movdqa	0x60($const), %xmm14	# .LNOT
-
-	movdqu	0x10($inp), %xmm6	# load round 1 key
 	lea	0x10($inp), $inp
+	movdqa	0x00($const), %xmm0	# 0x01...
+	movdqa	0x10($const), %xmm1	# 0x02...
+	movdqa	0x20($const), %xmm2	# 0x04...
+	movdqa	0x30($const), %xmm3	# 0x08...
+	movdqa	0x40($const), %xmm4	# .LM0
+	pcmpeqd	%xmm5, %xmm5		# .LNOT
+
+	movdqu	($inp), %xmm6		# load round 1 key
 	movdqa	%xmm7, ($out)		# save round 0 key
 	lea	0x10($out), $out
 	dec	$rounds
 	jmp	.Lkey_loop
 .align	16
 .Lkey_loop:
-	pshufb	%xmm13, %xmm6		# .LM0
-	movdqa	%xmm6, %xmm7
-___
-	&bitslice_key	(map("%xmm$_",(0..7, 8..12)));
-$code.=<<___;
-	pxor	%xmm14, %xmm5		# "pnot"
-	pxor	%xmm14, %xmm6
-	pxor	%xmm14, %xmm0
-	pxor	%xmm14, %xmm1
-	lea	0x10($inp), $inp
-	movdqa	%xmm0, 0x00($out)	# write bit-sliced round key
-	movdqa	%xmm1, 0x10($out)
-	movdqa	%xmm2, 0x20($out)
-	movdqa	%xmm3, 0x30($out)
-	movdqa	%xmm4, 0x40($out)
-	movdqa	%xmm5, 0x50($out)
-	movdqa	%xmm6, 0x60($out)
-	movdqa	%xmm7, 0x70($out)
+	pshufb	%xmm4, %xmm6		# .LM0
+
+	movdqa	%xmm0,	%xmm8
+	movdqa	%xmm1,	%xmm9
+
+	pand	%xmm6,	%xmm8
+	pand	%xmm6,	%xmm9
+	movdqa	%xmm2,	%xmm10
+	pcmpeqb	%xmm0,	%xmm8
+	psllq	\$4,	%xmm0		# 0x10...
+	movdqa	%xmm3,	%xmm11
+	pcmpeqb	%xmm1,	%xmm9
+	psllq	\$4,	%xmm1		# 0x20...
+
+	pand	%xmm6,	%xmm10
+	pand	%xmm6,	%xmm11
+	movdqa	%xmm0,	%xmm12
+	pcmpeqb	%xmm2,	%xmm10
+	psllq	\$4,	%xmm2		# 0x40...
+	movdqa	%xmm1,	%xmm13
+	pcmpeqb	%xmm3,	%xmm11
+	psllq	\$4,	%xmm3		# 0x80...
+
+	movdqa	%xmm2,	%xmm14
+	movdqa	%xmm3,	%xmm15
+	 pxor	%xmm5,	%xmm8		# "pnot"
+	 pxor	%xmm5,	%xmm9
+
+	pand	%xmm6,	%xmm12
+	pand	%xmm6,	%xmm13
+	 movdqa	%xmm8, 0x00($out)	# write bit-sliced round key
+	pcmpeqb	%xmm0,	%xmm12
+	psrlq	\$4,	%xmm0		# 0x01...
+	 movdqa	%xmm9, 0x10($out)
+	pcmpeqb	%xmm1,	%xmm13
+	psrlq	\$4,	%xmm1		# 0x02...
+	 lea	0x10($inp), $inp
+
+	pand	%xmm6,	%xmm14
+	pand	%xmm6,	%xmm15
+	 movdqa	%xmm10, 0x20($out)
+	pcmpeqb	%xmm2,	%xmm14
+	psrlq	\$4,	%xmm2		# 0x04...
+	 movdqa	%xmm11, 0x30($out)
+	pcmpeqb	%xmm3,	%xmm15
+	psrlq	\$4,	%xmm3		# 0x08...
+	 movdqu	($inp), %xmm6		# load next round key
+
+	pxor	%xmm5, %xmm13		# "pnot"
+	pxor	%xmm5, %xmm14
+	movdqa	%xmm12, 0x40($out)
+	movdqa	%xmm13, 0x50($out)
+	movdqa	%xmm14, 0x60($out)
+	movdqa	%xmm15, 0x70($out)
 	lea	0x80($out),$out
-	movdqu	($inp), %xmm6		# load next round key
 	dec	$rounds
 	jnz	.Lkey_loop
 
-	movdqa	0x70($const), %xmm7	# .L63
+	movdqa	0x50($const), %xmm7	# .L63
 	#movdqa	%xmm6, ($out)		# don't save last round key
 	ret
 .size	_bsaes_key_convert,.-_bsaes_key_convert
@@ -2800,14 +2837,8 @@
 	.quad	0x0504070600030201, 0x0f0e0d0c0a09080b
 .LSRM0:
 	.quad	0x0304090e00050a0f, 0x01060b0c0207080d
-.LM0:
-	.quad	0x02060a0e03070b0f, 0x0004080c0105090d
 .LM0SR:
 	.quad	0x0a0e02060f03070b, 0x0004080c05090d01
-.LNOT:		# magic constants
-	.quad	0xffffffffffffffff, 0xffffffffffffffff
-.L63:
-	.quad	0x6363636363636363, 0x6363636363636363
 .LSWPUP:	# byte-swap upper dword
 	.quad	0x0706050403020100, 0x0c0d0e0f0b0a0908
 .LSWPUPM0SR:
@@ -2830,6 +2861,15 @@
 	.quad	0x0000000000000000, 0x0000000800000000
 .Lxts_magic:
 	.long	0x87,0,1,0
+.Lmasks:
+	.quad	0x0101010101010101, 0x0101010101010101
+	.quad	0x0202020202020202, 0x0202020202020202
+	.quad	0x0404040404040404, 0x0404040404040404
+	.quad	0x0808080808080808, 0x0808080808080808
+.LM0:
+	.quad	0x02060a0e03070b0f, 0x0004080c0105090d
+.L63:
+	.quad	0x6363636363636363, 0x6363636363636363
 .asciz	"Bit-sliced AES for x86_64/SSSE3, Emilia Käsper, Peter Schwabe, Andy Polyakov"
 .align	64
 .size	_bsaes_const,.-_bsaes_const
diff --git a/crypto/aes/asm/vpaes-x86.pl b/crypto/aes/asm/vpaes-x86.pl
index 84a6f6d..1533e2c 100644
--- a/crypto/aes/asm/vpaes-x86.pl
+++ b/crypto/aes/asm/vpaes-x86.pl
@@ -843,6 +843,8 @@
 	&mov	($out,&wparam(1));		# out
 	&mov	($round,&wparam(2));		# len
 	&mov	($key,&wparam(3));		# key
+	&sub	($round,16);
+	&jc	(&label("cbc_abort"));
 	&lea	($base,&DWP(-56,"esp"));
 	&mov	($const,&wparam(4));		# ivp
 	&and	($base,-16);
@@ -853,7 +855,6 @@
 	&mov	(&DWP(48,"esp"),$base);
 
 	&mov	(&DWP(0,"esp"),$out);		# save out
-	&sub	($round,16);
 	&mov	(&DWP(4,"esp"),$key)		# save key
 	&mov	(&DWP(8,"esp"),$const);		# save ivp
 	&mov	($out,$round);			# $out works as $len
@@ -896,6 +897,7 @@
 	&mov	($base,&DWP(8,"esp"));		# restore ivp
 	&mov	("esp",&DWP(48,"esp"));
 	&movdqu	(&QWP(0,$base),"xmm1");		# write IV
+&set_label("cbc_abort");
 &function_end("${PREFIX}_cbc_encrypt");
 
 &asm_finish();
diff --git a/crypto/aes/asm/vpaes-x86_64.pl b/crypto/aes/asm/vpaes-x86_64.pl
index 0254702..37998db 100644
--- a/crypto/aes/asm/vpaes-x86_64.pl
+++ b/crypto/aes/asm/vpaes-x86_64.pl
@@ -263,7 +263,7 @@
 	pshufb  %xmm2,  %xmm4	# 4 = sbou
 	pxor	%xmm0,  %xmm4	# 4 = sb1u + k
 	movdqa	0x70(%r10), %xmm0	# 0 : sbot
-	movdqa	.Lk_sr-.Lk_dsbd(%r11), %xmm2
+	movdqa	-0x160(%r11), %xmm2	# .Lk_sr-.Lk_dsbd=-0x160
 	pshufb  %xmm3,	%xmm0	# 0 = sb1t
 	pxor	%xmm4,	%xmm0	# 0 = A
 	pshufb	%xmm2,	%xmm0
@@ -869,6 +869,8 @@
 ___
 ($len,$key)=($key,$len);
 $code.=<<___;
+	sub	\$16,$len
+	jc	.Lcbc_abort
 ___
 $code.=<<___ if ($win64);
 	lea	-0xb8(%rsp),%rsp
@@ -887,7 +889,6 @@
 $code.=<<___;
 	movdqu	($ivp),%xmm6		# load IV
 	sub	$inp,$out
-	sub	\$16,$len
 	call	_vpaes_preheat
 	cmp	\$0,${enc}d
 	je	.Lcbc_dec_loop
@@ -932,6 +933,7 @@
 .Lcbc_epilogue:
 ___
 $code.=<<___;
+.Lcbc_abort:
 	ret
 .size	${PREFIX}_cbc_encrypt,.-${PREFIX}_cbc_encrypt
 ___
diff --git a/crypto/asn1/a_d2i_fp.c b/crypto/asn1/a_d2i_fp.c
index e3e3fec..52b2ebd 100644
--- a/crypto/asn1/a_d2i_fp.c
+++ b/crypto/asn1/a_d2i_fp.c
@@ -164,7 +164,7 @@
 			{
 			want-=(len-off);
 
-			if (len+want < len || !BUF_MEM_grow_clean(b,len+want))
+			if (len + want < len || !BUF_MEM_grow_clean(b,len+want))
 				{
 				ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
 				goto err;
@@ -232,11 +232,11 @@
 				{
 				want-=(len-off);
 				if (want > INT_MAX /* BIO_read takes an int length */ ||
-				    len+want < len)
-					{
-					ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
-					goto err;
-					}
+					len+want < len)
+						{
+						ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
+						goto err;
+						}
 				if (!BUF_MEM_grow_clean(b,len+want))
 					{
 					ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
@@ -277,6 +277,7 @@
 		ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
 		goto err;
 		}
+
 	*pb = b;
 	return off;
 err:
diff --git a/crypto/asn1/tasn_prn.c b/crypto/asn1/tasn_prn.c
index 4536980..542a091 100644
--- a/crypto/asn1/tasn_prn.c
+++ b/crypto/asn1/tasn_prn.c
@@ -446,11 +446,11 @@
 	return 1;
 	}
 
-static int asn1_print_boolean_ctx(BIO *out, const int bool,
+static int asn1_print_boolean_ctx(BIO *out, int boolval,
 							const ASN1_PCTX *pctx)
 	{
 	const char *str;
-	switch (bool)
+	switch (boolval)
 		{
 		case -1:
 		str = "BOOL ABSENT";
@@ -574,10 +574,10 @@
 		{
 		case V_ASN1_BOOLEAN:
 			{
-			int bool = *(int *)fld;
-			if (bool == -1)
-				bool = it->size;
-			ret = asn1_print_boolean_ctx(out, bool, pctx);
+			int boolval = *(int *)fld;
+			if (boolval == -1)
+				boolval = it->size;
+			ret = asn1_print_boolean_ctx(out, boolval, pctx);
 			}
 		break;
 
diff --git a/crypto/bio/b_sock.c b/crypto/bio/b_sock.c
index d47310d..41f958b 100644
--- a/crypto/bio/b_sock.c
+++ b/crypto/bio/b_sock.c
@@ -960,7 +960,6 @@
 #endif
 	return(ret == 0);
 	}
-#endif
 
 int BIO_socket_nbio(int s, int mode)
 	{
@@ -973,3 +972,4 @@
 #endif
 	return(ret == 0);
 	}
+#endif
diff --git a/crypto/bio/bio_lib.c b/crypto/bio/bio_lib.c
index e12bc3a..9c9646a 100644
--- a/crypto/bio/bio_lib.c
+++ b/crypto/bio/bio_lib.c
@@ -521,40 +521,40 @@
 
 BIO *BIO_dup_chain(BIO *in)
 	{
-	BIO *ret=NULL,*eoc=NULL,*bio,*new;
+	BIO *ret=NULL,*eoc=NULL,*bio,*new_bio;
 
 	for (bio=in; bio != NULL; bio=bio->next_bio)
 		{
-		if ((new=BIO_new(bio->method)) == NULL) goto err;
-		new->callback=bio->callback;
-		new->cb_arg=bio->cb_arg;
-		new->init=bio->init;
-		new->shutdown=bio->shutdown;
-		new->flags=bio->flags;
+		if ((new_bio=BIO_new(bio->method)) == NULL) goto err;
+		new_bio->callback=bio->callback;
+		new_bio->cb_arg=bio->cb_arg;
+		new_bio->init=bio->init;
+		new_bio->shutdown=bio->shutdown;
+		new_bio->flags=bio->flags;
 
 		/* This will let SSL_s_sock() work with stdin/stdout */
-		new->num=bio->num;
+		new_bio->num=bio->num;
 
-		if (!BIO_dup_state(bio,(char *)new))
+		if (!BIO_dup_state(bio,(char *)new_bio))
 			{
-			BIO_free(new);
+			BIO_free(new_bio);
 			goto err;
 			}
 
 		/* copy app data */
-		if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new->ex_data,
+		if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data,
 					&bio->ex_data))
 			goto err;
 
 		if (ret == NULL)
 			{
-			eoc=new;
+			eoc=new_bio;
 			ret=eoc;
 			}
 		else
 			{
-			BIO_push(eoc,new);
-			eoc=new;
+			BIO_push(eoc,new_bio);
+			eoc=new_bio;
 			}
 		}
 	return(ret);
diff --git a/crypto/bn/bn_gf2m.c b/crypto/bn/bn_gf2m.c
index 08ab9fd..8a4dc20 100644
--- a/crypto/bn/bn_gf2m.c
+++ b/crypto/bn/bn_gf2m.c
@@ -628,8 +628,11 @@
 			}
 		if (ubits==vbits)
 			{
-			bn_correct_top(u);
-			ubits = BN_num_bits(u);
+			BN_ULONG ul;
+			int utop = (ubits-1)/BN_BITS2;
+
+			while ((ul=udp[utop])==0 && utop) utop--;
+			ubits = utop*BN_BITS2 + BN_num_bits_word(ul);
 			}
 		}
 	bn_correct_top(b);
diff --git a/crypto/cmac/cmac.c b/crypto/cmac/cmac.c
index b586026..8b72b09 100644
--- a/crypto/cmac/cmac.c
+++ b/crypto/cmac/cmac.c
@@ -179,6 +179,8 @@
 			return 0;
 		if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv))
 			return 0;
+		memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(&ctx->cctx));
+		ctx->nlast_block = 0;
 		return 1;
 		}
 	/* Initialiase context */
diff --git a/crypto/evp/e_aes_cbc_hmac_sha1.c b/crypto/evp/e_aes_cbc_hmac_sha1.c
index 278c6ca..710fb79 100644
--- a/crypto/evp/e_aes_cbc_hmac_sha1.c
+++ b/crypto/evp/e_aes_cbc_hmac_sha1.c
@@ -83,6 +83,8 @@
     } aux;
     } EVP_AES_HMAC_SHA1;
 
+#define NO_PAYLOAD_LENGTH	((size_t)-1)
+
 #if	defined(AES_ASM) &&	( \
 	defined(__x86_64)	|| defined(__x86_64__)	|| \
 	defined(_M_AMD64)	|| defined(_M_X64)	|| \
@@ -124,7 +126,7 @@
 	key->tail = key->head;
 	key->md   = key->head;
 
-	key->payload_length = 0;
+	key->payload_length = NO_PAYLOAD_LENGTH;
 
 	return ret<0?0:1;
 	}
@@ -185,7 +187,7 @@
 	if (len%AES_BLOCK_SIZE) return 0;
 
 	if (ctx->encrypt) {
-		if (plen==0)
+		if (plen==NO_PAYLOAD_LENGTH)
 			plen = len;
 		else if (len!=((plen+SHA_DIGEST_LENGTH+AES_BLOCK_SIZE)&-AES_BLOCK_SIZE))
 			return 0;
@@ -271,7 +273,7 @@
 		}
 	}
 
-	key->payload_length = 0;
+	key->payload_length = NO_PAYLOAD_LENGTH;
 
 	return 1;
 	}
diff --git a/crypto/evp/e_rc4_hmac_md5.c b/crypto/evp/e_rc4_hmac_md5.c
index eaa7a53..5f1490c 100644
--- a/crypto/evp/e_rc4_hmac_md5.c
+++ b/crypto/evp/e_rc4_hmac_md5.c
@@ -75,6 +75,8 @@
     size_t		payload_length;
     } EVP_RC4_HMAC_MD5;
 
+#define NO_PAYLOAD_LENGTH	((size_t)-1)
+
 void rc4_md5_enc (RC4_KEY *key, const void *in0, void *out,
 		MD5_CTX *ctx,const void *inp,size_t blocks);
 
@@ -93,7 +95,7 @@
 	key->tail = key->head;
 	key->md   = key->head;
 
-	key->payload_length = 0;
+	key->payload_length = NO_PAYLOAD_LENGTH;
 
 	return 1;
 	}
@@ -101,8 +103,7 @@
 #if	!defined(OPENSSL_NO_ASM) &&	( \
 	defined(__x86_64)	|| defined(__x86_64__)	|| \
 	defined(_M_AMD64)	|| defined(_M_X64)	|| \
-	defined(__INTEL__)		) && \
-	!(defined(__APPLE__) && defined(__MACH__))
+	defined(__INTEL__)		)
 #define	STITCHED_CALL
 #endif
 
@@ -120,18 +121,20 @@
 		md5_off = MD5_CBLOCK-key->md.num,
 		blocks;
 	unsigned int l;
+		  extern unsigned int OPENSSL_ia32cap_P[];
 #endif
 	size_t	plen = key->payload_length;
 
-	if (plen && len!=(plen+MD5_DIGEST_LENGTH)) return 0;
+	if (plen!=NO_PAYLOAD_LENGTH && len!=(plen+MD5_DIGEST_LENGTH)) return 0;
 
 	if (ctx->encrypt) {
-		if (plen==0) plen = len;
+		if (plen==NO_PAYLOAD_LENGTH) plen = len;
 #if defined(STITCHED_CALL)
 		/* cipher has to "fall behind" */
 		if (rc4_off>md5_off) md5_off+=MD5_CBLOCK;
 
-		if (plen>md5_off && (blocks=(plen-md5_off)/MD5_CBLOCK)) {
+		   if (plen>md5_off && (blocks=(plen-md5_off)/MD5_CBLOCK) &&
+		          (OPENSSL_ia32cap_P[0]&(1<<20))==0) {
 			MD5_Update(&key->md,in,md5_off);
 			RC4(&key->ks,rc4_off,in,out);
 
@@ -171,7 +174,8 @@
 		if (md5_off>rc4_off)	rc4_off += 2*MD5_CBLOCK;
 		else			rc4_off += MD5_CBLOCK;
 
-		if (len>rc4_off && (blocks=(len-rc4_off)/MD5_CBLOCK)) {
+		   if (len>rc4_off && (blocks=(len-rc4_off)/MD5_CBLOCK) &&
+		          (OPENSSL_ia32cap_P[0]&(1<<20))==0) {
 			RC4(&key->ks,rc4_off,in,out);
 			MD5_Update(&key->md,out,md5_off);
 
@@ -191,7 +195,7 @@
 #endif
 		/* decrypt HMAC at once */
 		RC4(&key->ks,len-rc4_off,in+rc4_off,out+rc4_off);
-		if (plen) {	/* "TLS" mode of operation */
+		if (plen!=NO_PAYLOAD_LENGTH) {	/* "TLS" mode of operation */
 			MD5_Update(&key->md,out+md5_off,plen-md5_off);
 
 			/* calculate HMAC and verify it */
@@ -207,7 +211,7 @@
 		}
 	}
 
-	key->payload_length = 0;
+	key->payload_length = NO_PAYLOAD_LENGTH;
 
 	return 1;
 	}
diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c
index 6910726..8835d9a 100644
--- a/crypto/evp/evp_enc.c
+++ b/crypto/evp/evp_enc.c
@@ -170,7 +170,8 @@
 #endif
 
 #ifdef OPENSSL_FIPS
-		return FIPS_cipherinit(ctx, cipher, key, iv, enc);
+		if (FIPS_mode())
+			return FIPS_cipherinit(ctx, cipher, key, iv, enc);
 #else
 		ctx->cipher=cipher;
 		if (ctx->cipher->ctx_size)
@@ -207,7 +208,8 @@
 skip_to_init:
 #endif
 #ifdef OPENSSL_FIPS
-	return FIPS_cipherinit(ctx, cipher, key, iv, enc);
+	if (FIPS_mode())
+		return FIPS_cipherinit(ctx, cipher, key, iv, enc);
 #else
 	/* we assume block size is a power of 2 in *cryptUpdate */
 	OPENSSL_assert(ctx->cipher->block_size == 1
diff --git a/crypto/evp/p5_crpt.c b/crypto/evp/p5_crpt.c
index 7d9c1f0..294cc90 100644
--- a/crypto/evp/p5_crpt.c
+++ b/crypto/evp/p5_crpt.c
@@ -138,5 +138,6 @@
 	OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH);
 	rv = 1;
 	err:
+	EVP_MD_CTX_cleanup(&ctx);
 	return rv;
 }
diff --git a/crypto/modes/asm/ghash-s390x.pl b/crypto/modes/asm/ghash-s390x.pl
index 48cb08d..6a40d5d 100644
--- a/crypto/modes/asm/ghash-s390x.pl
+++ b/crypto/modes/asm/ghash-s390x.pl
@@ -138,7 +138,7 @@
 .align	32
 .Lsoft_ghash:
 ___
-$cdoe.=<<___ if ($flavour =~ /3[12]/);
+$code.=<<___ if ($flavour =~ /3[12]/);
 	llgfr	$len,$len
 ___
 $code.=<<___;
diff --git a/crypto/modes/modes_lcl.h b/crypto/modes/modes_lcl.h
index 7a82a98..b6dc3c3 100644
--- a/crypto/modes/modes_lcl.h
+++ b/crypto/modes/modes_lcl.h
@@ -45,7 +45,7 @@
 #  define BSWAP4(x) ({	u32 ret=(x);			\
 			asm ("bswapl %0"		\
 			: "+r"(ret));	ret;		})
-# elif (defined(__i386) || defined(__i386__))
+# elif (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)
 #  define BSWAP8(x) ({	u32 lo=(u64)(x)>>32,hi=(x);	\
 			asm ("bswapl %0; bswapl %1"	\
 			: "+r"(hi),"+r"(lo));		\
diff --git a/crypto/opensslv.h b/crypto/opensslv.h
index bf42556..20e889e 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	0x1000100fL
+#define OPENSSL_VERSION_NUMBER	0x1000101fL
 #ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1-fips 14 Mar 2012"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1a-fips 19 Apr 2012"
 #else
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1 14 Mar 2012"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1a 19 Apr 2012"
 #endif
 #define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
 
diff --git a/crypto/perlasm/x86masm.pl b/crypto/perlasm/x86masm.pl
index 3af0453..96b1b73 100644
--- a/crypto/perlasm/x86masm.pl
+++ b/crypto/perlasm/x86masm.pl
@@ -16,7 +16,7 @@
     # fix hexadecimal constants
     for (@arg) { s/(?<![\w\$\.])0x([0-9a-f]+)/0$1h/oi; }
 
-    if ($opcode =~ /lea/ && @arg[1] =~ s/.*PTR\s+([^\[]+)$/$1/)	# no []
+    if ($opcode =~ /lea/ && @arg[1] =~ s/.*PTR\s+(\(.*\))$/OFFSET $1/)	# no []
     {	$opcode="mov";	}
     elsif ($opcode !~ /movq/)
     {	# fix xmm references
diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c
index fae8eda..77fda3b 100644
--- a/crypto/pkcs7/pk7_doit.c
+++ b/crypto/pkcs7/pk7_doit.c
@@ -430,6 +430,8 @@
 	STACK_OF(X509_ALGOR) *md_sk=NULL;
 	STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
 	PKCS7_RECIP_INFO *ri=NULL;
+       unsigned char *ek = NULL, *tkey = NULL;
+       int eklen = 0, tkeylen = 0;
 
 	i=OBJ_obj2nid(p7->type);
 	p7->state=PKCS7_S_HEADER;
@@ -507,8 +509,6 @@
 		int max;
 		X509_OBJECT ret;
 #endif
-		unsigned char *ek = NULL, *tkey = NULL;
-		int eklen, tkeylen;
 
 		if ((etmp=BIO_new(BIO_f_cipher())) == NULL)
 			{
@@ -609,11 +609,13 @@
 			{
 			OPENSSL_cleanse(ek,eklen);
 			OPENSSL_free(ek);
+                       ek = NULL;
 			}
 		if (tkey)
 			{
 			OPENSSL_cleanse(tkey,tkeylen);
 			OPENSSL_free(tkey);
+                       tkey = NULL;
 			}
 
 		if (out == NULL)
@@ -656,6 +658,16 @@
 	if (0)
 		{
 err:
+               if (ek)
+                       {
+                       OPENSSL_cleanse(ek,eklen);
+                       OPENSSL_free(ek);
+                       }
+               if (tkey)
+                       {
+                       OPENSSL_cleanse(tkey,tkeylen);
+                       OPENSSL_free(tkey);
+                       }
 		if (out != NULL) BIO_free_all(out);
 		if (btmp != NULL) BIO_free_all(btmp);
 		if (etmp != NULL) BIO_free_all(etmp);
diff --git a/crypto/rc4/asm/rc4-s390x.pl b/crypto/rc4/asm/rc4-s390x.pl
index 1aa7548..7528ece 100644
--- a/crypto/rc4/asm/rc4-s390x.pl
+++ b/crypto/rc4/asm/rc4-s390x.pl
@@ -171,10 +171,10 @@
 $iinp="%r8";
 
 $code.=<<___;
-.globl	RC4_set_key
-.type	RC4_set_key,\@function
+.globl	private_RC4_set_key
+.type	private_RC4_set_key,\@function
 .align	64
-RC4_set_key:
+private_RC4_set_key:
 	stm${g}	%r6,%r8,6*$SIZE_T($sp)
 	lhi	$cnt,256
 	la	$idx,0(%r0)
@@ -210,7 +210,7 @@
 .Ldone:
 	lm${g}	%r6,%r8,6*$SIZE_T($sp)
 	br	$rp
-.size	RC4_set_key,.-RC4_set_key
+.size	private_RC4_set_key,.-private_RC4_set_key
 
 ___
 }
diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c
index 3a6e04a..38525a8 100644
--- a/crypto/x509/x509_lu.c
+++ b/crypto/x509/x509_lu.c
@@ -87,7 +87,7 @@
 	if (ctx == NULL) return;
 	if (	(ctx->method != NULL) &&
 		(ctx->method->free != NULL))
-		ctx->method->free(ctx);
+		(*ctx->method->free)(ctx);
 	OPENSSL_free(ctx);
 	}
 
diff --git a/include/openssl/opensslv.h b/include/openssl/opensslv.h
index bf42556..20e889e 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	0x1000100fL
+#define OPENSSL_VERSION_NUMBER	0x1000101fL
 #ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1-fips 14 Mar 2012"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1a-fips 19 Apr 2012"
 #else
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1 14 Mar 2012"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1a 19 Apr 2012"
 #endif
 #define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
 
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 90d5537..912a2f7 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -2076,6 +2076,7 @@
 #define SSL_F_DTLS1_ACCEPT				 246
 #define SSL_F_DTLS1_ADD_CERT_TO_BUF			 295
 #define SSL_F_DTLS1_BUFFER_RECORD			 247
+#define SSL_F_DTLS1_CHECK_TIMEOUT_NUM			 316
 #define SSL_F_DTLS1_CLIENT_HELLO			 248
 #define SSL_F_DTLS1_CONNECT				 249
 #define SSL_F_DTLS1_ENC					 250
diff --git a/openssl.config b/openssl.config
index 80d99de..067ad6f 100644
--- a/openssl.config
+++ b/openssl.config
@@ -203,8 +203,7 @@
 handshake_cutthrough.patch \
 jsse.patch \
 sha1_armv4_large.patch \
-openssl_cn_22286.patch \
-asn1_overflow.patch \
+cn_22455.patch \
 "
 
 OPENSSL_PATCHES_progs_SOURCES="\
diff --git a/openssl.version b/openssl.version
index c7b738e..092a791 100644
--- a/openssl.version
+++ b/openssl.version
@@ -1,2 +1,2 @@
 # also update ThirdPartyProject.prop
-OPENSSL_VERSION=1.0.1
+OPENSSL_VERSION=1.0.1a
diff --git a/patches/README b/patches/README
index 7ca9de8..2360365 100644
--- a/patches/README
+++ b/patches/README
@@ -34,11 +34,8 @@
 
 This patch eliminates memory stores to addresses below SP.
 
-openssl_cn_22286.patch
+cn_22455.patch
 
-use client version when deciding whether to send supported signature algorithms extension
-http://cvs.openssl.org/chngview?cn=22286
-
-asn1_overflow.patch
-
-Fix integer overflow in ASN.1 parsing functions.
+fix for non-x86 build issue in crypto/e_rc4_hmac_md5.c
+e_rc4_hmac_md5.c: last commit was inappropriate for non-x86[_64] platforms [from HEAD]. PR: 2792
+http://cvs.openssl.org/chngview?cn=22455
diff --git a/patches/asn1_overflow.patch b/patches/asn1_overflow.patch
deleted file mode 100644
index bb6c379..0000000
--- a/patches/asn1_overflow.patch
+++ /dev/null
@@ -1,175 +0,0 @@
---- openssl/crypto/asn1/a_d2i_fp.c	2011-02-01 06:46:34.000000000 -0800
-+++ openssl/crypto/asn1/a_d2i_fp.c	2012-04-02 10:54:56.000000000 -0700
-@@ -57,6 +57,7 @@
-  */
- 
- #include <stdio.h>
-+#include <limits.h>
- #include "cryptlib.h"
- #include <openssl/buffer.h>
- #include <openssl/asn1_mac.h>
-@@ -143,17 +144,11 @@
- 	BUF_MEM *b;
- 	unsigned char *p;
- 	int i;
--	int ret=-1;
- 	ASN1_const_CTX c;
--	int want=HEADER_SIZE;
-+	size_t want=HEADER_SIZE;
- 	int eos=0;
--#if defined(__GNUC__) && defined(__ia64)
--	/* pathetic compiler bug in all known versions as of Nov. 2002 */
--	long off=0;
--#else
--	int off=0;
--#endif
--	int len=0;
-+	size_t off=0;
-+	size_t len=0;
- 
- 	b=BUF_MEM_new();
- 	if (b == NULL)
-@@ -169,7 +164,7 @@
- 			{
- 			want-=(len-off);
- 
--			if (!BUF_MEM_grow_clean(b,len+want))
-+			if (len+want < len || !BUF_MEM_grow_clean(b,len+want))
- 				{
- 				ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
- 				goto err;
-@@ -181,7 +176,14 @@
- 				goto err;
- 				}
- 			if (i > 0)
-+				{
-+				if (len+i < len)
-+					{
-+					ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
-+					goto err;
-+					}
- 				len+=i;
-+				}
- 			}
- 		/* else data already loaded */
- 
-@@ -206,6 +208,11 @@
- 			{
- 			/* no data body so go round again */
- 			eos++;
-+			if (eos < 0)
-+				{
-+				ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_HEADER_TOO_LONG);
-+				goto err;
-+				}
- 			want=HEADER_SIZE;
- 			}
- 		else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC))
-@@ -220,10 +227,16 @@
- 		else 
- 			{
- 			/* suck in c.slen bytes of data */
--			want=(int)c.slen;
-+			want=c.slen;
- 			if (want > (len-off))
- 				{
- 				want-=(len-off);
-+				if (want > INT_MAX /* BIO_read takes an int length */ ||
-+				    len+want < len)
-+					{
-+					ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
-+					goto err;
-+					}
- 				if (!BUF_MEM_grow_clean(b,len+want))
- 					{
- 					ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
-@@ -238,11 +251,18 @@
- 						    ASN1_R_NOT_ENOUGH_DATA);
- 						goto err;
- 						}
-+					/* This can't overflow because
-+					 * |len+want| didn't overflow. */
- 					len+=i;
--					want -= i;
-+					want-=i;
- 					}
- 				}
--			off+=(int)c.slen;
-+			if (off + c.slen < off)
-+				{
-+				ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
-+				goto err;
-+				}
-+			off+=c.slen;
- 			if (eos <= 0)
- 				{
- 				break;
-@@ -252,9 +272,14 @@
- 			}
- 		}
- 
-+	if (off > INT_MAX)
-+		{
-+		ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
-+		goto err;
-+		}
- 	*pb = b;
- 	return off;
- err:
- 	if (b != NULL) BUF_MEM_free(b);
--	return(ret);
-+	return -1;
- 	}
---- openssl/crypto/buffer/buffer.c	2011-02-01 06:46:34.000000000 -0800
-+++ openssl/crypto/buffer/buffer.c	2012-04-02 10:54:56.000000000 -0700
-@@ -60,6 +60,11 @@
- #include "cryptlib.h"
- #include <openssl/buffer.h>
- 
-+/* LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That
-+ * function is applied in several functions in this file and this limit ensures
-+ * that the result fits in an int. */
-+#define LIMIT_BEFORE_EXPANSION 0x5ffffffc
-+
- BUF_MEM *BUF_MEM_new(void)
- 	{
- 	BUF_MEM *ret;
-@@ -105,6 +110,12 @@
- 		str->length=len;
- 		return(len);
- 		}
-+	/* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
-+	if (len > LIMIT_BEFORE_EXPANSION)
-+		{
-+		BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE);
-+		return 0;
-+		}
- 	n=(len+3)/3*4;
- 	if (str->data == NULL)
- 		ret=OPENSSL_malloc(n);
-@@ -142,6 +153,12 @@
- 		str->length=len;
- 		return(len);
- 		}
-+	/* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
-+	if (len > LIMIT_BEFORE_EXPANSION)
-+		{
-+		BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE);
-+		return 0;
-+		}
- 	n=(len+3)/3*4;
- 	if (str->data == NULL)
- 		ret=OPENSSL_malloc(n);
---- openssl/crypto/mem.c	2011-02-02 16:53:02.000000000 -0800
-+++ openssl/crypto/mem.c	2012-04-02 10:54:56.000000000 -0700
-@@ -334,6 +334,10 @@
- 
- 	if (num <= 0) return NULL;
- 
-+	/* We don't support shrinking the buffer. Note the memcpy that copies
-+	 * |old_len| bytes to the new buffer, below. */
-+	if (num < old_len) return NULL;
-+
- 	if (realloc_debug_func != NULL)
- 		realloc_debug_func(str, NULL, num, file, line, 0);
- 	ret=malloc_ex_func(num,file,line);
diff --git a/patches/cn_22455.patch b/patches/cn_22455.patch
new file mode 100644
index 0000000..c1cae52
--- /dev/null
+++ b/patches/cn_22455.patch
@@ -0,0 +1,40 @@
+--- a/crypto/evp/e_rc4_hmac_md5.c	2012/04/18 17:51:33	1.1.2.5
++++ b/crypto/evp/e_rc4_hmac_md5.c	2012/04/19 20:43:02	1.1.2.6
+@@ -121,6 +121,7 @@
+ 		md5_off = MD5_CBLOCK-key->md.num,
+ 		blocks;
+ 	unsigned int l;
++		  extern unsigned int OPENSSL_ia32cap_P[];
+ #endif
+ 	size_t	plen = key->payload_length;
+ 
+@@ -132,7 +133,8 @@
+ 		/* cipher has to "fall behind" */
+ 		if (rc4_off>md5_off) md5_off+=MD5_CBLOCK;
+ 
+-		if (plen>md5_off && (blocks=(plen-md5_off)/MD5_CBLOCK)) {
++		   if (plen>md5_off && (blocks=(plen-md5_off)/MD5_CBLOCK) &&
++		          (OPENSSL_ia32cap_P[0]&(1<<20))==0) {
+ 			MD5_Update(&key->md,in,md5_off);
+ 			RC4(&key->ks,rc4_off,in,out);
+ 
+@@ -172,7 +174,8 @@
+ 		if (md5_off>rc4_off)	rc4_off += 2*MD5_CBLOCK;
+ 		else			rc4_off += MD5_CBLOCK;
+ 
+-		if (len>rc4_off && (blocks=(len-rc4_off)/MD5_CBLOCK)) {
++		   if (len>rc4_off && (blocks=(len-rc4_off)/MD5_CBLOCK) &&
++		          (OPENSSL_ia32cap_P[0]&(1<<20))==0) {
+ 			RC4(&key->ks,rc4_off,in,out);
+ 			MD5_Update(&key->md,out,md5_off);
+ 
+@@ -289,8 +292,6 @@
+ 
+ const EVP_CIPHER *EVP_rc4_hmac_md5(void)
+ 	{
+-	extern unsigned int OPENSSL_ia32cap_P[];
+-	/* RC4_CHAR flag ------------vvvvv */
+-	return(OPENSSL_ia32cap_P[0]&(1<<20) ? NULL : &r4_hmac_md5_cipher);
++	return(&r4_hmac_md5_cipher);
+ 	}
+ #endif
diff --git a/patches/openssl_cn_22286.patch b/patches/openssl_cn_22286.patch
deleted file mode 100644
index 87419a4..0000000
--- a/patches/openssl_cn_22286.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- openssl/ssl/t1_lib.c
-+++ openssl/ssl/t1_lib.c
-@@ -544,7 +544,7 @@
- 		}
-		skip_ext:
- 
--	if (TLS1_get_version(s) >= TLS1_2_VERSION)
-+	if (TLS1_get_client_version(s) >= TLS1_2_VERSION)
- 		{
-		if ((size_t)(limit - ret) < sizeof(tls12_sigalgs) + 6)
- 			return NULL; 
diff --git a/ssl/bio_ssl.c b/ssl/bio_ssl.c
index eedac8a..e9552ca 100644
--- a/ssl/bio_ssl.c
+++ b/ssl/bio_ssl.c
@@ -538,6 +538,7 @@
 
 BIO *BIO_new_ssl_connect(SSL_CTX *ctx)
 	{
+#ifndef OPENSSL_NO_SOCK
 	BIO *ret=NULL,*con=NULL,*ssl=NULL;
 
 	if ((con=BIO_new(BIO_s_connect())) == NULL)
@@ -549,6 +550,7 @@
 	return(ret);
 err:
 	if (con != NULL) BIO_free(con);
+#endif
 	return(NULL);
 	}
 
diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c
index 56f6253..f61f718 100644
--- a/ssl/d1_lib.c
+++ b/ssl/d1_lib.c
@@ -412,7 +412,7 @@
 	if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
 		{
 		/* fail the connection, enough alerts have been sent */
-		SSLerr(SSL_F_DTLS1_HANDLE_TIMEOUT,SSL_R_READ_TIMEOUT_EXPIRED);
+		SSLerr(SSL_F_DTLS1_CHECK_TIMEOUT_NUM,SSL_R_READ_TIMEOUT_EXPIRED);
 		return -1;
 		}
 
diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c
index 5822379..29421da 100644
--- a/ssl/d1_srvr.c
+++ b/ssl/d1_srvr.c
@@ -920,7 +920,7 @@
 		p=s->s3->server_random;
 		Time=(unsigned long)time(NULL);			/* Time */
 		l2n(Time,p);
-		RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-sizeof(Time));
+		RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4);
 		/* Do the message type and length last */
 		d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
 
diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c
index 6a75843..96d717c 100644
--- a/ssl/s23_clnt.c
+++ b/ssl/s23_clnt.c
@@ -287,12 +287,14 @@
 
 	if (ssl2_compat && ssl23_no_ssl2_ciphers(s))
 		ssl2_compat = 0;
-
+#ifndef OPENSSL_NO_TLS1_2_CLIENT
 	if (!(s->options & SSL_OP_NO_TLSv1_2))
 		{
 		version = TLS1_2_VERSION;
 		}
-	else if (!(s->options & SSL_OP_NO_TLSv1_1))
+	else
+#endif
+	if (!(s->options & SSL_OP_NO_TLSv1_1))
 		{
 		version = TLS1_1_VERSION;
 		}
@@ -467,6 +469,15 @@
 				SSLerr(SSL_F_SSL23_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
 				return -1;
 				}
+#ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH
+			/* Some servers hang if client hello > 256 bytes
+			 * as hack workaround chop number of supported ciphers
+			 * to keep it well below this if we use TLS v1.2
+			 */
+			if (TLS1_get_version(s) >= TLS1_2_VERSION
+				&& i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH)
+				i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1;
+#endif
 			s2n(i,p);
 			p+=i;
 
@@ -521,8 +532,13 @@
 			d=buf;
 			*(d++) = SSL3_RT_HANDSHAKE;
 			*(d++) = version_major;
-			*(d++) = version_minor; /* arguably we should send the *lowest* suported version here
-			                         * (indicating, e.g., TLS 1.0 in "SSL 3.0 format") */
+			/* Some servers hang if we use long client hellos
+			 * and a record number > TLS 1.0.
+			 */
+			if (TLS1_get_client_version(s) > TLS1_VERSION)
+				*(d++) = 1;
+			else
+				*(d++) = version_minor;
 			s2n((int)l,d);
 
 			/* number of bytes to write */
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index b5b7f11..d24bf52 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -808,6 +808,15 @@
 			SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE);
 			goto err;
 			}
+#ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH
+			/* Some servers hang if client hello > 256 bytes
+			 * as hack workaround chop number of supported ciphers
+			 * to keep it well below this if we use TLS v1.2
+			 */
+			if (TLS1_get_version(s) >= TLS1_2_VERSION
+				&& i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH)
+				i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1;
+#endif
 		s2n(i,p);
 		p+=i;
 
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index a2ea25a..8b8350c 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -1081,7 +1081,7 @@
 	SSL_aRSA,
 	SSL_eNULL,
 	SSL_SHA256,
-	SSL_SSLV3,
+	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS,
 	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	0,
@@ -1097,7 +1097,7 @@
 	SSL_aRSA,
 	SSL_AES128,
 	SSL_SHA256,
-	SSL_TLSV1,
+	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
@@ -1113,7 +1113,7 @@
 	SSL_aRSA,
 	SSL_AES256,
 	SSL_SHA256,
-	SSL_TLSV1,
+	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
@@ -1129,7 +1129,7 @@
 	SSL_aDH,
 	SSL_AES128,
 	SSL_SHA256,
-	SSL_TLSV1,
+	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
@@ -1145,7 +1145,7 @@
 	SSL_aDH,
 	SSL_AES128,
 	SSL_SHA256,
-	SSL_TLSV1,
+	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
@@ -1161,7 +1161,7 @@
 	SSL_aDSS,
 	SSL_AES128,
 	SSL_SHA256,
-	SSL_TLSV1,
+	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
@@ -1395,7 +1395,7 @@
 	SSL_aRSA,
 	SSL_AES128,
 	SSL_SHA256,
-	SSL_TLSV1,
+	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
@@ -1411,7 +1411,7 @@
 	SSL_aDH,
 	SSL_AES256,
 	SSL_SHA256,
-	SSL_TLSV1,
+	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
@@ -1427,7 +1427,7 @@
 	SSL_aDH,
 	SSL_AES256,
 	SSL_SHA256,
-	SSL_TLSV1,
+	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
@@ -1443,7 +1443,7 @@
 	SSL_aDSS,
 	SSL_AES256,
 	SSL_SHA256,
-	SSL_TLSV1,
+	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
@@ -1459,7 +1459,7 @@
 	SSL_aRSA,
 	SSL_AES256,
 	SSL_SHA256,
-	SSL_TLSV1,
+	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
@@ -1475,7 +1475,7 @@
 	SSL_aNULL,
 	SSL_AES128,
 	SSL_SHA256,
-	SSL_TLSV1,
+	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
@@ -1491,7 +1491,7 @@
 	SSL_aNULL,
 	SSL_AES256,
 	SSL_SHA256,
-	SSL_TLSV1,
+	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index bd0571f..1cc3442 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -691,10 +691,14 @@
 	if (	(sess == NULL) ||
 		(s->enc_write_ctx == NULL) ||
 		(EVP_MD_CTX_md(s->write_hash) == NULL))
+		{
+#if 1
+		clear=s->enc_write_ctx?0:1;	/* must be AEAD cipher */
+#else
 		clear=1;
-
-	if (clear)
+#endif
 		mac_size=0;
+		}
 	else
 		{
 		mac_size=EVP_MD_CTX_size(s->write_hash);
@@ -775,7 +779,14 @@
 	wr->type=type;
 
 	*(p++)=(s->version>>8);
-	*(p++)=s->version&0xff;
+	/* Some servers hang if iniatial client hello is larger than 256
+	 * bytes and record version number > TLS 1.0
+	 */
+	if (s->state == SSL3_ST_CW_CLNT_HELLO_B
+				&& TLS1_get_version(s) > TLS1_VERSION)
+		*(p++) = 0x1;
+	else
+		*(p++)=s->version&0xff;
 
 	/* field where we are to write out packet length */
 	plen=p; 
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index 0dbddde..ee42fa5 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -2942,7 +2942,7 @@
 	if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY)
 		{
 		s->s3->tmp.reuse_message=1;
-		if ((peer != NULL) && (type | EVP_PKT_SIGN))
+		if ((peer != NULL) && (type & EVP_PKT_SIGN))
 			{
 			al=SSL_AD_UNEXPECTED_MESSAGE;
 			SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE);
diff --git a/ssl/ssl.h b/ssl/ssl.h
index 90d5537..912a2f7 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -2076,6 +2076,7 @@
 #define SSL_F_DTLS1_ACCEPT				 246
 #define SSL_F_DTLS1_ADD_CERT_TO_BUF			 295
 #define SSL_F_DTLS1_BUFFER_RECORD			 247
+#define SSL_F_DTLS1_CHECK_TIMEOUT_NUM			 316
 #define SSL_F_DTLS1_CLIENT_HELLO			 248
 #define SSL_F_DTLS1_CONNECT				 249
 #define SSL_F_DTLS1_ENC					 250
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index 1a143a7..5898701 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -616,18 +616,19 @@
 		{
 		const EVP_CIPHER *evp;
 
-		if	(s->ssl_version >= TLS1_VERSION &&
-			 c->algorithm_enc == SSL_RC4 &&
+		if (s->ssl_version>>8 != TLS1_VERSION_MAJOR ||
+		    s->ssl_version < TLS1_VERSION)
+			return 1;
+
+		if	(c->algorithm_enc == SSL_RC4 &&
 			 c->algorithm_mac == SSL_MD5 &&
 			 (evp=EVP_get_cipherbyname("RC4-HMAC-MD5")))
 			*enc = evp, *md = NULL;
-		else if (s->ssl_version >= TLS1_VERSION &&
-			 c->algorithm_enc == SSL_AES128 &&
+		else if (c->algorithm_enc == SSL_AES128 &&
 			 c->algorithm_mac == SSL_SHA1 &&
 			 (evp=EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1")))
 			*enc = evp, *md = NULL;
-		else if (s->ssl_version >= TLS1_VERSION &&
-			 c->algorithm_enc == SSL_AES256 &&
+		else if (c->algorithm_enc == SSL_AES256 &&
 			 c->algorithm_mac == SSL_SHA1 &&
 			 (evp=EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1")))
 			*enc = evp, *md = NULL;
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index 2039a0c..3f9480c 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -80,6 +80,7 @@
 {ERR_FUNC(SSL_F_DTLS1_ACCEPT),	"DTLS1_ACCEPT"},
 {ERR_FUNC(SSL_F_DTLS1_ADD_CERT_TO_BUF),	"DTLS1_ADD_CERT_TO_BUF"},
 {ERR_FUNC(SSL_F_DTLS1_BUFFER_RECORD),	"DTLS1_BUFFER_RECORD"},
+{ERR_FUNC(SSL_F_DTLS1_CHECK_TIMEOUT_NUM),	"DTLS1_CHECK_TIMEOUT_NUM"},
 {ERR_FUNC(SSL_F_DTLS1_CLIENT_HELLO),	"DTLS1_CLIENT_HELLO"},
 {ERR_FUNC(SSL_F_DTLS1_CONNECT),	"DTLS1_CONNECT"},
 {ERR_FUNC(SSL_F_DTLS1_ENC),	"DTLS1_ENC"},