From 52628ee3f51f011b463aaedb1a28aa0524b43cb3 Mon Sep 17 00:00:00 2001
From: miod <>
Date: Sun, 13 Apr 2014 15:16:40 +0000
Subject: Import OpenSSL 1.0.1g

---
 src/lib/libcrypto/aes/asm/aes-mips.pl              |  20 +-
 src/lib/libcrypto/aes/asm/aes-parisc.pl            |   3 +-
 src/lib/libcrypto/aes/asm/aes-s390x.pl             |  95 +++----
 src/lib/libcrypto/aes/asm/aes-x86_64.pl            |   3 +-
 src/lib/libcrypto/aes/asm/aesni-sha1-x86_64.pl     |   3 +-
 src/lib/libcrypto/aes/asm/aesni-x86_64.pl          |   3 +-
 src/lib/libcrypto/aes/asm/bsaes-x86_64.pl          |  76 +++++-
 src/lib/libcrypto/aes/asm/vpaes-x86_64.pl          |   5 +-
 src/lib/libcrypto/armcap.c                         |   2 +-
 src/lib/libcrypto/asn1/a_int.c                     |   2 +-
 src/lib/libcrypto/asn1/a_strex.c                   |   1 +
 src/lib/libcrypto/asn1/a_verify.c                  |   6 +
 src/lib/libcrypto/asn1/asn1_err.c                  |   2 +-
 src/lib/libcrypto/asn1/x_pubkey.c                  |   5 +-
 src/lib/libcrypto/bio/bss_dgram.c                  |  91 ++++---
 src/lib/libcrypto/bio/bss_log.c                    |   2 +-
 src/lib/libcrypto/bn/asm/mips-mont.pl              |   2 +-
 src/lib/libcrypto/bn/asm/mips.pl                   |  46 ++--
 src/lib/libcrypto/bn/asm/modexp512-x86_64.pl       |   3 +-
 src/lib/libcrypto/bn/asm/parisc-mont.pl            |   4 +-
 src/lib/libcrypto/bn/asm/x86_64-gf2m.pl            |   3 +-
 src/lib/libcrypto/bn/asm/x86_64-mont.pl            |   3 +-
 src/lib/libcrypto/bn/asm/x86_64-mont5.pl           |   7 +-
 src/lib/libcrypto/bn/bn.h                          |  11 +
 src/lib/libcrypto/bn/bn_div.c                      |   2 +
 src/lib/libcrypto/bn/bn_gcd.c                      |   1 +
 src/lib/libcrypto/bn/bn_lcl.h                      |  11 +-
 src/lib/libcrypto/bn/bn_lib.c                      |  52 ++++
 src/lib/libcrypto/bn/bn_nist.c                     |  55 ++--
 src/lib/libcrypto/bn/bn_word.c                     |  25 +-
 src/lib/libcrypto/buffer/buffer.c                  |   4 +-
 src/lib/libcrypto/buffer/buffer.h                  |   2 +-
 src/lib/libcrypto/camellia/asm/cmll-x86_64.pl      |   3 +-
 src/lib/libcrypto/cms/cms_cd.c                     |   2 +
 src/lib/libcrypto/cms/cms_enc.c                    |   2 +-
 src/lib/libcrypto/cms/cms_lib.c                    |   4 -
 src/lib/libcrypto/conf/conf_mall.c                 |   1 +
 src/lib/libcrypto/cryptlib.c                       |  18 +-
 src/lib/libcrypto/cryptlib.h                       |   2 +-
 src/lib/libcrypto/crypto.h                         |  11 +-
 src/lib/libcrypto/des/set_key.c                    |   3 +-
 src/lib/libcrypto/des/str2key.c                    |   2 +-
 src/lib/libcrypto/doc/ERR_get_error.pod            |   7 +-
 src/lib/libcrypto/doc/EVP_BytesToKey.pod           |   2 +-
 src/lib/libcrypto/doc/EVP_EncryptInit.pod          |   2 +-
 src/lib/libcrypto/doc/EVP_PKEY_CTX_ctrl.pod        |   2 +-
 src/lib/libcrypto/doc/EVP_PKEY_decrypt.pod         |   2 +-
 src/lib/libcrypto/doc/EVP_PKEY_derive.pod          |   2 +-
 src/lib/libcrypto/doc/EVP_PKEY_encrypt.pod         |   2 +-
 .../libcrypto/doc/EVP_PKEY_get_default_digest.pod  |   2 +-
 src/lib/libcrypto/doc/EVP_PKEY_keygen.pod          |   2 +-
 src/lib/libcrypto/doc/EVP_PKEY_sign.pod            |   2 +-
 src/lib/libcrypto/doc/EVP_PKEY_verify.pod          |   2 +-
 src/lib/libcrypto/doc/EVP_PKEY_verify_recover.pod  | 103 ++++++++
 src/lib/libcrypto/doc/X509_STORE_CTX_get_error.pod |   2 +
 .../libcrypto/doc/X509_VERIFY_PARAM_set_flags.pod  |   2 +-
 src/lib/libcrypto/ec/ec.h                          |  28 +-
 src/lib/libcrypto/ec/ec2_mult.c                    |  27 +-
 src/lib/libcrypto/ec/ec_ameth.c                    |   2 +-
 src/lib/libcrypto/ec/ec_asn1.c                     |   6 +-
 src/lib/libcrypto/ec/ec_key.c                      |  13 +-
 src/lib/libcrypto/ec/ec_lib.c                      |  10 +-
 src/lib/libcrypto/ec/ec_pmeth.c                    |   2 +-
 src/lib/libcrypto/ec/ecp_mont.c                    |   1 -
 src/lib/libcrypto/ecdh/ech_key.c                   |   3 -
 src/lib/libcrypto/ecdh/ech_lib.c                   |  11 +-
 src/lib/libcrypto/ecdsa/ecs_lib.c                  |  11 +-
 src/lib/libcrypto/engine/eng_list.c                |   1 +
 src/lib/libcrypto/err/err_all.c                    |  19 +-
 src/lib/libcrypto/evp/bio_b64.c                    |   2 +-
 src/lib/libcrypto/evp/digest.c                     |   8 +-
 src/lib/libcrypto/evp/e_aes.c                      |  21 +-
 src/lib/libcrypto/evp/e_aes_cbc_hmac_sha1.c        | 217 ++++++++++++++--
 src/lib/libcrypto/evp/e_des3.c                     |   6 +-
 src/lib/libcrypto/evp/evp.h                        |  15 +-
 src/lib/libcrypto/evp/evp_err.c                    |   6 +
 src/lib/libcrypto/evp/m_dss.c                      |   2 +-
 src/lib/libcrypto/evp/m_dss1.c                     |   2 +-
 src/lib/libcrypto/evp/m_sha1.c                     |   2 +-
 src/lib/libcrypto/evp/p5_crpt2.c                   |  40 ++-
 src/lib/libcrypto/evp/p_sign.c                     |   2 +-
 src/lib/libcrypto/evp/p_verify.c                   |   2 +-
 src/lib/libcrypto/md4/md4_dgst.c                   |  31 +--
 src/lib/libcrypto/md4/md4_locl.h                   |   8 +-
 src/lib/libcrypto/md5/asm/md5-x86_64.pl            |   3 +-
 src/lib/libcrypto/md5/md5_locl.h                   |   8 +-
 src/lib/libcrypto/modes/asm/ghash-alpha.pl         |  25 +-
 src/lib/libcrypto/modes/asm/ghash-parisc.pl        |   1 +
 src/lib/libcrypto/modes/asm/ghash-x86.pl           |   6 +-
 src/lib/libcrypto/modes/asm/ghash-x86_64.pl        |   3 +-
 src/lib/libcrypto/modes/cbc128.c                   |  25 +-
 src/lib/libcrypto/modes/ccm128.c                   |   2 +-
 src/lib/libcrypto/modes/cts128.c                   |  28 +-
 src/lib/libcrypto/modes/gcm128.c                   | 196 ++++++++++++--
 src/lib/libcrypto/modes/modes_lcl.h                |   9 +-
 src/lib/libcrypto/objects/o_names.c                |   2 +-
 src/lib/libcrypto/ocsp/ocsp_vfy.c                  |  10 +-
 src/lib/libcrypto/opensslv.h                       |   6 +-
 src/lib/libcrypto/pariscid.pl                      |  41 +--
 src/lib/libcrypto/pem/pem_all.c                    | 161 ++++++++++++
 src/lib/libcrypto/pem/pem_info.c                   |   1 +
 src/lib/libcrypto/pem/pem_lib.c                    |  27 +-
 src/lib/libcrypto/pem/pem_seal.c                   |   6 +-
 src/lib/libcrypto/perlasm/cbc.pl                   |   2 +-
 src/lib/libcrypto/pkcs12/p12_crt.c                 |   7 +
 src/lib/libcrypto/pkcs12/p12_key.c                 |  24 +-
 src/lib/libcrypto/pkcs7/bio_pk7.c                  |   2 +-
 src/lib/libcrypto/ppccap.c                         |  11 +
 src/lib/libcrypto/rand/rand.h                      |   1 +
 src/lib/libcrypto/rand/rand_err.c                  |   1 +
 src/lib/libcrypto/rand/rand_lib.c                  |  15 +-
 src/lib/libcrypto/rand/randfile.c                  |   2 +
 src/lib/libcrypto/rc4/asm/rc4-md5-x86_64.pl        |   3 +-
 src/lib/libcrypto/rc4/asm/rc4-parisc.pl            |   3 +-
 src/lib/libcrypto/rc4/asm/rc4-x86_64.pl            |   3 +-
 src/lib/libcrypto/ripemd/rmd_dgst.c                |  30 +--
 src/lib/libcrypto/ripemd/rmd_locl.h                |  10 +-
 src/lib/libcrypto/rsa/rsa.h                        |   2 +-
 src/lib/libcrypto/rsa/rsa_ameth.c                  |   8 +-
 src/lib/libcrypto/rsa/rsa_chk.c                    |   6 +
 src/lib/libcrypto/rsa/rsa_eay.c                    |   6 +-
 src/lib/libcrypto/rsa/rsa_oaep.c                   |   2 +-
 src/lib/libcrypto/rsa/rsa_pmeth.c                  |   2 +
 src/lib/libcrypto/sha/asm/sha1-armv4-large.pl      |   2 +-
 src/lib/libcrypto/sha/asm/sha1-ia64.pl             |   3 +-
 src/lib/libcrypto/sha/asm/sha1-parisc.pl           |   3 +-
 src/lib/libcrypto/sha/asm/sha1-sparcv9a.pl         |   2 +-
 src/lib/libcrypto/sha/asm/sha1-x86_64.pl           |   7 +-
 src/lib/libcrypto/sha/asm/sha512-586.pl            |  16 +-
 src/lib/libcrypto/sha/asm/sha512-mips.pl           |   2 +-
 src/lib/libcrypto/sha/asm/sha512-parisc.pl         |   2 +
 src/lib/libcrypto/sha/asm/sha512-x86_64.pl         |   3 +-
 src/lib/libcrypto/sha/sha1_one.c                   |   2 +-
 src/lib/libcrypto/sha/sha1dgst.c                   |   2 +-
 src/lib/libcrypto/sha/sha256.c                     |   6 +-
 src/lib/libcrypto/sha/sha512.c                     |   9 +-
 src/lib/libcrypto/sha/sha_locl.h                   |  40 +--
 src/lib/libcrypto/sparccpuid.S                     |   4 +-
 src/lib/libcrypto/ui/ui_openssl.c                  |   6 +
 src/lib/libcrypto/whrlpool/asm/wp-mmx.pl           |   2 +-
 src/lib/libcrypto/whrlpool/asm/wp-x86_64.pl        |   3 +-
 src/lib/libcrypto/x509/by_dir.c                    |   6 +-
 src/lib/libcrypto/x509/x509_cmp.c                  |  15 +-
 src/lib/libcrypto/x509/x509_vfy.c                  |  20 +-
 src/lib/libcrypto/x509/x_all.c                     |   2 +
 src/lib/libcrypto/x509v3/v3_purp.c                 |   4 +-
 src/lib/libcrypto/x86_64cpuid.pl                   |   3 +-
 src/lib/libcrypto/x86cpuid.pl                      |   6 +-
 src/lib/libssl/d1_both.c                           |  39 ++-
 src/lib/libssl/d1_clnt.c                           |  36 ++-
 src/lib/libssl/d1_enc.c                            |  59 ++---
 src/lib/libssl/d1_lib.c                            |   1 +
 src/lib/libssl/d1_pkt.c                            |  98 ++++---
 src/lib/libssl/d1_srtp.c                           |   5 +-
 src/lib/libssl/d1_srvr.c                           |  29 ++-
 src/lib/libssl/dtls1.h                             |   8 +-
 src/lib/libssl/s23_clnt.c                          |  29 ++-
 src/lib/libssl/s3_both.c                           |  22 +-
 src/lib/libssl/s3_clnt.c                           |  11 +-
 src/lib/libssl/s3_lib.c                            |  36 ++-
 src/lib/libssl/s3_pkt.c                            | 111 ++++----
 src/lib/libssl/s3_srvr.c                           |  39 +--
 src/lib/libssl/ssl.h                               |  21 +-
 src/lib/libssl/ssl3.h                              |  15 ++
 src/lib/libssl/ssl_algs.c                          |   1 +
 src/lib/libssl/ssl_cert.c                          |   4 +-
 src/lib/libssl/ssl_ciph.c                          |   5 +-
 src/lib/libssl/ssl_err.c                           |   1 +
 src/lib/libssl/ssl_lib.c                           |  26 +-
 src/lib/libssl/ssl_locl.h                          |  47 +++-
 src/lib/libssl/ssl_rsa.c                           |  14 +-
 src/lib/libssl/t1_enc.c                            | 190 +++++++-------
 src/lib/libssl/t1_lib.c                            | 283 ++++++++++++++++-----
 src/lib/libssl/test/cms-test.pl                    |   4 +-
 src/lib/libssl/test/testssl                        |  17 ++
 src/lib/libssl/tls1.h                              |   6 +
 176 files changed, 2294 insertions(+), 963 deletions(-)
 create mode 100644 src/lib/libcrypto/doc/EVP_PKEY_verify_recover.pod

diff --git a/src/lib/libcrypto/aes/asm/aes-mips.pl b/src/lib/libcrypto/aes/asm/aes-mips.pl
index 2ce6deffc8..e52395421b 100644
--- a/src/lib/libcrypto/aes/asm/aes-mips.pl
+++ b/src/lib/libcrypto/aes/asm/aes-mips.pl
@@ -1036,9 +1036,9 @@ _mips_AES_set_encrypt_key:
 	nop
 .end	_mips_AES_set_encrypt_key
 
-.globl	AES_set_encrypt_key
-.ent	AES_set_encrypt_key
-AES_set_encrypt_key:
+.globl	private_AES_set_encrypt_key
+.ent	private_AES_set_encrypt_key
+private_AES_set_encrypt_key:
 	.frame	$sp,$FRAMESIZE,$ra
 	.mask	$SAVED_REGS_MASK,-$SZREG
 	.set	noreorder
@@ -1060,7 +1060,7 @@ $code.=<<___ if ($flavour =~ /nubi/i);	# optimize non-nubi prologue
 ___
 $code.=<<___ if ($flavour !~ /o32/i);	# non-o32 PIC-ification
 	.cplocal	$Tbl
-	.cpsetup	$pf,$zero,AES_set_encrypt_key
+	.cpsetup	$pf,$zero,private_AES_set_encrypt_key
 ___
 $code.=<<___;
 	.set	reorder
@@ -1083,7 +1083,7 @@ ___
 $code.=<<___;
 	jr	$ra
 	$PTR_ADD $sp,$FRAMESIZE
-.end	AES_set_encrypt_key
+.end	private_AES_set_encrypt_key
 ___
 
 my ($head,$tail)=($inp,$bits);
@@ -1091,9 +1091,9 @@ my ($tp1,$tp2,$tp4,$tp8,$tp9,$tpb,$tpd,$tpe)=($a4,$a5,$a6,$a7,$s0,$s1,$s2,$s3);
 my ($m,$x80808080,$x7f7f7f7f,$x1b1b1b1b)=($at,$t0,$t1,$t2);
 $code.=<<___;
 .align	5
-.globl	AES_set_decrypt_key
-.ent	AES_set_decrypt_key
-AES_set_decrypt_key:
+.globl	private_AES_set_decrypt_key
+.ent	private_AES_set_decrypt_key
+private_AES_set_decrypt_key:
 	.frame	$sp,$FRAMESIZE,$ra
 	.mask	$SAVED_REGS_MASK,-$SZREG
 	.set	noreorder
@@ -1115,7 +1115,7 @@ $code.=<<___ if ($flavour =~ /nubi/i);	# optimize non-nubi prologue
 ___
 $code.=<<___ if ($flavour !~ /o32/i);	# non-o32 PIC-ification
 	.cplocal	$Tbl
-	.cpsetup	$pf,$zero,AES_set_decrypt_key
+	.cpsetup	$pf,$zero,private_AES_set_decrypt_key
 ___
 $code.=<<___;
 	.set	reorder
@@ -1226,7 +1226,7 @@ ___
 $code.=<<___;
 	jr	$ra
 	$PTR_ADD $sp,$FRAMESIZE
-.end	AES_set_decrypt_key
+.end	private_AES_set_decrypt_key
 ___
 }}}
 
diff --git a/src/lib/libcrypto/aes/asm/aes-parisc.pl b/src/lib/libcrypto/aes/asm/aes-parisc.pl
index c36b6a2270..714dcfbbe3 100644
--- a/src/lib/libcrypto/aes/asm/aes-parisc.pl
+++ b/src/lib/libcrypto/aes/asm/aes-parisc.pl
@@ -1015,7 +1015,8 @@ foreach (split("\n",$code)) {
 		$SIZE_T==4 ? sprintf("extru%s,%d,8,",$1,31-$2)
 		:            sprintf("extrd,u%s,%d,8,",$1,63-$2)/e;
 
-	s/,\*/,/ if ($SIZE_T==4);
+	s/,\*/,/			if ($SIZE_T==4);
+	s/\bbv\b(.*\(%r2\))/bve$1/	if ($SIZE_T==8);
 	print $_,"\n";
 }
 close STDOUT;
diff --git a/src/lib/libcrypto/aes/asm/aes-s390x.pl b/src/lib/libcrypto/aes/asm/aes-s390x.pl
index 445a1e6762..e75dcd0315 100644
--- a/src/lib/libcrypto/aes/asm/aes-s390x.pl
+++ b/src/lib/libcrypto/aes/asm/aes-s390x.pl
@@ -1598,11 +1598,11 @@ $code.=<<___ if(1);
 	lghi	$s1,0x7f
 	nr	$s1,%r0
 	lghi	%r0,0			# query capability vector
-	la	%r1,2*$SIZE_T($sp)
+	la	%r1,$tweak-16($sp)
 	.long	0xb92e0042		# km %r4,%r2
 	llihh	%r1,0x8000
 	srlg	%r1,%r1,32($s1)		# check for 32+function code
-	ng	%r1,2*$SIZE_T($sp)
+	ng	%r1,$tweak-16($sp)
 	lgr	%r0,$s0			# restore the function code
 	la	%r1,0($key1)		# restore $key1
 	jz	.Lxts_km_vanilla
@@ -1628,7 +1628,7 @@ $code.=<<___ if(1);
 
 	lrvg	$s0,$tweak+0($sp)	# load the last tweak
 	lrvg	$s1,$tweak+8($sp)
-	stmg	%r0,%r3,$tweak-32(%r1)	# wipe copy of the key
+	stmg	%r0,%r3,$tweak-32($sp)	# wipe copy of the key
 
 	nill	%r0,0xffdf		# switch back to original function code
 	la	%r1,0($key1)		# restore pointer to $key1
@@ -1684,11 +1684,9 @@ $code.=<<___;
 	lghi	$i1,0x87
 	srag	$i2,$s1,63		# broadcast upper bit
 	ngr	$i1,$i2			# rem
-	srlg	$i2,$s0,63		# carry bit from lower half
-	sllg	$s0,$s0,1
-	sllg	$s1,$s1,1
+	algr	$s0,$s0
+	alcgr	$s1,$s1
 	xgr	$s0,$i1
-	ogr	$s1,$i2
 .Lxts_km_start:
 	lrvgr	$i1,$s0			# flip byte order
 	lrvgr	$i2,$s1
@@ -1745,11 +1743,9 @@ $code.=<<___;
 	lghi	$i1,0x87
 	srag	$i2,$s1,63		# broadcast upper bit
 	ngr	$i1,$i2			# rem
-	srlg	$i2,$s0,63		# carry bit from lower half
-	sllg	$s0,$s0,1
-	sllg	$s1,$s1,1
+	algr	$s0,$s0
+	alcgr	$s1,$s1
 	xgr	$s0,$i1
-	ogr	$s1,$i2
 
 	ltr	$len,$len		# clear zero flag
 	br	$ra
@@ -1781,8 +1777,8 @@ $code.=<<___ if (!$softonly);
 	clr	%r0,%r1
 	jl	.Lxts_enc_software
 
+	st${g}	$ra,5*$SIZE_T($sp)
 	stm${g}	%r6,$s3,6*$SIZE_T($sp)
-	st${g}	$ra,14*$SIZE_T($sp)
 
 	sllg	$len,$len,4		# $len&=~15
 	slgr	$out,$inp
@@ -1830,9 +1826,9 @@ $code.=<<___ if (!$softonly);
 	stg	$i2,8($i3)
 
 .Lxts_enc_km_done:
-	l${g}	$ra,14*$SIZE_T($sp)
-	st${g}	$sp,$tweak($sp)		# wipe tweak
-	st${g}	$sp,$tweak($sp)
+	stg	$sp,$tweak+0($sp)	# wipe tweak
+	stg	$sp,$tweak+8($sp)
+	l${g}	$ra,5*$SIZE_T($sp)
 	lm${g}	%r6,$s3,6*$SIZE_T($sp)
 	br	$ra
 .align	16
@@ -1843,12 +1839,11 @@ $code.=<<___;
 
 	slgr	$out,$inp
 
-	xgr	$s0,$s0			# clear upper half
-	xgr	$s1,$s1
-	lrv	$s0,$stdframe+4($sp)	# load secno
-	lrv	$s1,$stdframe+0($sp)
-	xgr	$s2,$s2
-	xgr	$s3,$s3
+	l${g}	$s3,$stdframe($sp)	# ivp
+	llgf	$s0,0($s3)		# load iv
+	llgf	$s1,4($s3)
+	llgf	$s2,8($s3)
+	llgf	$s3,12($s3)
 	stm${g}	%r2,%r5,2*$SIZE_T($sp)
 	la	$key,0($key2)
 	larl	$tbl,AES_Te
@@ -1864,11 +1859,9 @@ $code.=<<___;
 	lghi	%r1,0x87
 	srag	%r0,$s3,63		# broadcast upper bit
 	ngr	%r1,%r0			# rem
-	srlg	%r0,$s1,63		# carry bit from lower half
-	sllg	$s1,$s1,1
-	sllg	$s3,$s3,1
+	algr	$s1,$s1
+	alcgr	$s3,$s3
 	xgr	$s1,%r1
-	ogr	$s3,%r0
 	lrvgr	$s1,$s1			# flip byte order
 	lrvgr	$s3,$s3
 	srlg	$s0,$s1,32		# smash the tweak to 4x32-bits 
@@ -1917,11 +1910,9 @@ $code.=<<___;
 	lghi	%r1,0x87
 	srag	%r0,$s3,63		# broadcast upper bit
 	ngr	%r1,%r0			# rem
-	srlg	%r0,$s1,63		# carry bit from lower half
-	sllg	$s1,$s1,1
-	sllg	$s3,$s3,1
+	algr	$s1,$s1
+	alcgr	$s3,$s3
 	xgr	$s1,%r1
-	ogr	$s3,%r0
 	lrvgr	$s1,$s1			# flip byte order
 	lrvgr	$s3,$s3
 	srlg	$s0,$s1,32		# smash the tweak to 4x32-bits 
@@ -1956,7 +1947,8 @@ $code.=<<___;
 .size	AES_xts_encrypt,.-AES_xts_encrypt
 ___
 # void AES_xts_decrypt(const char *inp,char *out,size_t len,
-#	const AES_KEY *key1, const AES_KEY *key2,u64 secno);
+#	const AES_KEY *key1, const AES_KEY *key2,
+#	const unsigned char iv[16]);
 #
 $code.=<<___;
 .globl	AES_xts_decrypt
@@ -1988,8 +1980,8 @@ $code.=<<___ if (!$softonly);
 	clr	%r0,%r1
 	jl	.Lxts_dec_software
 
+	st${g}	$ra,5*$SIZE_T($sp)
 	stm${g}	%r6,$s3,6*$SIZE_T($sp)
-	st${g}	$ra,14*$SIZE_T($sp)
 
 	nill	$len,0xfff0		# $len&=~15
 	slgr	$out,$inp
@@ -2028,11 +2020,9 @@ $code.=<<___ if (!$softonly);
 	lghi	$i1,0x87
 	srag	$i2,$s1,63		# broadcast upper bit
 	ngr	$i1,$i2			# rem
-	srlg	$i2,$s0,63		# carry bit from lower half
-	sllg	$s0,$s0,1
-	sllg	$s1,$s1,1
+	algr	$s0,$s0
+	alcgr	$s1,$s1
 	xgr	$s0,$i1
-	ogr	$s1,$i2
 	lrvgr	$i1,$s0			# flip byte order
 	lrvgr	$i2,$s1
 
@@ -2075,9 +2065,9 @@ $code.=<<___ if (!$softonly);
 	stg	$s2,0($i3)
 	stg	$s3,8($i3)
 .Lxts_dec_km_done:
-	l${g}	$ra,14*$SIZE_T($sp)
-	st${g}	$sp,$tweak($sp)		# wipe tweak
-	st${g}	$sp,$tweak($sp)
+	stg	$sp,$tweak+0($sp)	# wipe tweak
+	stg	$sp,$tweak+8($sp)
+	l${g}	$ra,5*$SIZE_T($sp)
 	lm${g}	%r6,$s3,6*$SIZE_T($sp)
 	br	$ra
 .align	16
@@ -2089,12 +2079,11 @@ $code.=<<___;
 	srlg	$len,$len,4
 	slgr	$out,$inp
 
-	xgr	$s0,$s0			# clear upper half
-	xgr	$s1,$s1
-	lrv	$s0,$stdframe+4($sp)	# load secno
-	lrv	$s1,$stdframe+0($sp)
-	xgr	$s2,$s2
-	xgr	$s3,$s3
+	l${g}	$s3,$stdframe($sp)	# ivp
+	llgf	$s0,0($s3)		# load iv
+	llgf	$s1,4($s3)
+	llgf	$s2,8($s3)
+	llgf	$s3,12($s3)
 	stm${g}	%r2,%r5,2*$SIZE_T($sp)
 	la	$key,0($key2)
 	larl	$tbl,AES_Te
@@ -2113,11 +2102,9 @@ $code.=<<___;
 	lghi	%r1,0x87
 	srag	%r0,$s3,63		# broadcast upper bit
 	ngr	%r1,%r0			# rem
-	srlg	%r0,$s1,63		# carry bit from lower half
-	sllg	$s1,$s1,1
-	sllg	$s3,$s3,1
+	algr	$s1,$s1
+	alcgr	$s3,$s3
 	xgr	$s1,%r1
-	ogr	$s3,%r0
 	lrvgr	$s1,$s1			# flip byte order
 	lrvgr	$s3,$s3
 	srlg	$s0,$s1,32		# smash the tweak to 4x32-bits 
@@ -2156,11 +2143,9 @@ $code.=<<___;
 	lghi	%r1,0x87
 	srag	%r0,$s3,63		# broadcast upper bit
 	ngr	%r1,%r0			# rem
-	srlg	%r0,$s1,63		# carry bit from lower half
-	sllg	$s1,$s1,1
-	sllg	$s3,$s3,1
+	algr	$s1,$s1
+	alcgr	$s3,$s3
 	xgr	$s1,%r1
-	ogr	$s3,%r0
 	lrvgr	$i2,$s1			# flip byte order
 	lrvgr	$i3,$s3
 	stmg	$i2,$i3,$tweak($sp)	# save the 1st tweak
@@ -2176,11 +2161,9 @@ $code.=<<___;
 	lghi	%r1,0x87
 	srag	%r0,$s3,63		# broadcast upper bit
 	ngr	%r1,%r0			# rem
-	srlg	%r0,$s1,63		# carry bit from lower half
-	sllg	$s1,$s1,1
-	sllg	$s3,$s3,1
+	algr	$s1,$s1
+	alcgr	$s3,$s3
 	xgr	$s1,%r1
-	ogr	$s3,%r0
 	lrvgr	$s1,$s1			# flip byte order
 	lrvgr	$s3,$s3
 	srlg	$s0,$s1,32		# smash the tweak to 4x32-bits
diff --git a/src/lib/libcrypto/aes/asm/aes-x86_64.pl b/src/lib/libcrypto/aes/asm/aes-x86_64.pl
index 48fa857d5b..34cbb5d844 100755
--- a/src/lib/libcrypto/aes/asm/aes-x86_64.pl
+++ b/src/lib/libcrypto/aes/asm/aes-x86_64.pl
@@ -36,7 +36,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 $verticalspin=1;	# unlike 32-bit version $verticalspin performs
 			# ~15% better on both AMD and Intel cores
diff --git a/src/lib/libcrypto/aes/asm/aesni-sha1-x86_64.pl b/src/lib/libcrypto/aes/asm/aesni-sha1-x86_64.pl
index c6f6b3334a..3c8f6c19e7 100644
--- a/src/lib/libcrypto/aes/asm/aesni-sha1-x86_64.pl
+++ b/src/lib/libcrypto/aes/asm/aesni-sha1-x86_64.pl
@@ -69,7 +69,8 @@ $avx=1 if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
 	   `ml64 2>&1` =~ /Version ([0-9]+)\./ &&
 	   $1>=10);
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 # void aesni_cbc_sha1_enc(const void *inp,
 #			void *out,
diff --git a/src/lib/libcrypto/aes/asm/aesni-x86_64.pl b/src/lib/libcrypto/aes/asm/aesni-x86_64.pl
index 499f3b3f42..0dbb194b8d 100644
--- a/src/lib/libcrypto/aes/asm/aesni-x86_64.pl
+++ b/src/lib/libcrypto/aes/asm/aesni-x86_64.pl
@@ -172,7 +172,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 $movkey = $PREFIX eq "aesni" ? "movups" : "movups";
 @_4args=$win64?	("%rcx","%rdx","%r8", "%r9") :	# Win64 order
diff --git a/src/lib/libcrypto/aes/asm/bsaes-x86_64.pl b/src/lib/libcrypto/aes/asm/bsaes-x86_64.pl
index c9c6312fa7..41b90f0844 100644
--- a/src/lib/libcrypto/aes/asm/bsaes-x86_64.pl
+++ b/src/lib/libcrypto/aes/asm/bsaes-x86_64.pl
@@ -83,9 +83,9 @@
 # Add decryption procedure. Performance in CPU cycles spent to decrypt
 # one byte out of 4096-byte buffer with 128-bit key is:
 #
-# Core 2	11.0
-# Nehalem	9.16
-# Atom		20.9
+# Core 2	9.83
+# Nehalem	7.74
+# Atom		19.0
 #
 # November 2011.
 #
@@ -105,7 +105,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 my ($inp,$out,$len,$key,$ivp)=("%rdi","%rsi","%rdx","%rcx");
 my @XMM=map("%xmm$_",(15,0..14));	# best on Atom, +10% over (0..15)
@@ -455,6 +456,7 @@ sub MixColumns {
 # modified to emit output in order suitable for feeding back to aesenc[last]
 my @x=@_[0..7];
 my @t=@_[8..15];
+my $inv=@_[16];	# optional
 $code.=<<___;
 	pshufd	\$0x93, @x[0], @t[0]	# x0 <<< 32
 	pshufd	\$0x93, @x[1], @t[1]
@@ -496,7 +498,8 @@ $code.=<<___;
 	pxor	@t[4], @t[0]
 	 pshufd	\$0x4E, @x[2], @x[6]
 	pxor	@t[5], @t[1]
-
+___
+$code.=<<___ if (!$inv);
 	pxor	@t[3], @x[4]
 	pxor	@t[7], @x[5]
 	pxor	@t[6], @x[3]
@@ -504,9 +507,20 @@ $code.=<<___;
 	pxor	@t[2], @x[6]
 	 movdqa	@t[1], @x[7]
 ___
+$code.=<<___ if ($inv);
+	pxor	@x[4], @t[3]
+	pxor	@t[7], @x[5]
+	pxor	@x[3], @t[6]
+	 movdqa	@t[0], @x[3]
+	pxor	@t[2], @x[6]
+	 movdqa	@t[6], @x[2]
+	 movdqa	@t[1], @x[7]
+	 movdqa	@x[6], @x[4]
+	 movdqa	@t[3], @x[6]
+___
 }
 
-sub InvMixColumns {
+sub InvMixColumns_orig {
 my @x=@_[0..7];
 my @t=@_[8..15];
 
@@ -660,6 +674,54 @@ $code.=<<___;
 ___
 }
 
+sub InvMixColumns {
+my @x=@_[0..7];
+my @t=@_[8..15];
+
+# Thanks to Jussi Kivilinna for providing pointer to
+#
+# | 0e 0b 0d 09 |   | 02 03 01 01 |   | 05 00 04 00 |
+# | 09 0e 0b 0d | = | 01 02 03 01 | x | 00 05 00 04 |
+# | 0d 09 0e 0b |   | 01 01 02 03 |   | 04 00 05 00 |
+# | 0b 0d 09 0e |   | 03 01 01 02 |   | 00 04 00 05 |
+
+$code.=<<___;
+	# multiplication by 0x05-0x00-0x04-0x00
+	pshufd	\$0x4E, @x[0], @t[0]
+	pshufd	\$0x4E, @x[6], @t[6]
+	pxor	@x[0], @t[0]
+	pshufd	\$0x4E, @x[7], @t[7]
+	pxor	@x[6], @t[6]
+	pshufd	\$0x4E, @x[1], @t[1]
+	pxor	@x[7], @t[7]
+	pshufd	\$0x4E, @x[2], @t[2]
+	pxor	@x[1], @t[1]
+	pshufd	\$0x4E, @x[3], @t[3]
+	pxor	@x[2], @t[2]
+	 pxor	@t[6], @x[0]
+	 pxor	@t[6], @x[1]
+	pshufd	\$0x4E, @x[4], @t[4]
+	pxor	@x[3], @t[3]
+	 pxor	@t[0], @x[2]
+	 pxor	@t[1], @x[3]
+	pshufd	\$0x4E, @x[5], @t[5]
+	pxor	@x[4], @t[4]
+	 pxor	@t[7], @x[1]
+	 pxor	@t[2], @x[4]
+	pxor	@x[5], @t[5]
+
+	 pxor	@t[7], @x[2]
+	 pxor	@t[6], @x[3]
+	 pxor	@t[6], @x[4]
+	 pxor	@t[3], @x[5]
+	 pxor	@t[4], @x[6]
+	 pxor	@t[7], @x[4]
+	 pxor	@t[7], @x[5]
+	 pxor	@t[5], @x[7]
+___
+	&MixColumns	(@x,@t,1);	# flipped 2<->3 and 4<->6
+}
+
 sub aesenc {				# not used
 my @b=@_[0..7];
 my @t=@_[8..15];
@@ -2027,6 +2089,8 @@ ___
 #	const unsigned char iv[16]);
 #
 my ($twmask,$twres,$twtmp)=@XMM[13..15];
+$arg6=~s/d$//;
+
 $code.=<<___;
 .globl	bsaes_xts_encrypt
 .type	bsaes_xts_encrypt,\@abi-omnipotent
diff --git a/src/lib/libcrypto/aes/asm/vpaes-x86_64.pl b/src/lib/libcrypto/aes/asm/vpaes-x86_64.pl
index 37998db5e1..bd7f45b850 100644
--- a/src/lib/libcrypto/aes/asm/vpaes-x86_64.pl
+++ b/src/lib/libcrypto/aes/asm/vpaes-x86_64.pl
@@ -56,7 +56,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 $PREFIX="vpaes";
 
@@ -1059,7 +1060,7 @@ _vpaes_consts:
 .Lk_dsbo:	# decryption sbox final output
 	.quad	0x1387EA537EF94000, 0xC7AA6DB9D4943E2D
 	.quad	0x12D7560F93441D00, 0xCA4B8159D8C58E9C
-.asciz	"Vector Permutaion AES for x86_64/SSSE3, Mike Hamburg (Stanford University)"
+.asciz	"Vector Permutation AES for x86_64/SSSE3, Mike Hamburg (Stanford University)"
 .align	64
 .size	_vpaes_consts,.-_vpaes_consts
 ___
diff --git a/src/lib/libcrypto/armcap.c b/src/lib/libcrypto/armcap.c
index 5258d2fbdd..9abaf396e5 100644
--- a/src/lib/libcrypto/armcap.c
+++ b/src/lib/libcrypto/armcap.c
@@ -23,7 +23,7 @@ unsigned int _armv7_tick(void);
 
 unsigned int OPENSSL_rdtsc(void)
 	{
-	if (OPENSSL_armcap_P|ARMV7_TICK)
+	if (OPENSSL_armcap_P & ARMV7_TICK)
 		return _armv7_tick();
 	else
 		return 0;
diff --git a/src/lib/libcrypto/asn1/a_int.c b/src/lib/libcrypto/asn1/a_int.c
index ad0d2506f6..297c45a9ff 100644
--- a/src/lib/libcrypto/asn1/a_int.c
+++ b/src/lib/libcrypto/asn1/a_int.c
@@ -116,7 +116,7 @@ int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
 	int pad=0,ret,i,neg;
 	unsigned char *p,*n,pb=0;
 
-	if ((a == NULL) || (a->data == NULL)) return(0);
+	if (a == NULL) return(0);
 	neg=a->type & V_ASN1_NEG;
 	if (a->length == 0)
 		ret=1;
diff --git a/src/lib/libcrypto/asn1/a_strex.c b/src/lib/libcrypto/asn1/a_strex.c
index 264ebf2393..ead37ac325 100644
--- a/src/lib/libcrypto/asn1/a_strex.c
+++ b/src/lib/libcrypto/asn1/a_strex.c
@@ -567,6 +567,7 @@ int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in)
 	if(mbflag == -1) return -1;
 	mbflag |= MBSTRING_FLAG;
 	stmp.data = NULL;
+	stmp.length = 0;
 	ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag, B_ASN1_UTF8STRING);
 	if(ret < 0) return ret;
 	*out = stmp.data;
diff --git a/src/lib/libcrypto/asn1/a_verify.c b/src/lib/libcrypto/asn1/a_verify.c
index 432722e409..fc84cd3d19 100644
--- a/src/lib/libcrypto/asn1/a_verify.c
+++ b/src/lib/libcrypto/asn1/a_verify.c
@@ -140,6 +140,12 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
 
 	int mdnid, pknid;
 
+	if (!pkey)
+		{
+		ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
+		return -1;
+		}
+
 	EVP_MD_CTX_init(&ctx);
 
 	/* Convert signature OID into digest and public key OIDs */
diff --git a/src/lib/libcrypto/asn1/asn1_err.c b/src/lib/libcrypto/asn1/asn1_err.c
index 1a30bf119b..aa60203ba8 100644
--- a/src/lib/libcrypto/asn1/asn1_err.c
+++ b/src/lib/libcrypto/asn1/asn1_err.c
@@ -305,7 +305,7 @@ static ERR_STRING_DATA ASN1_str_reasons[]=
 {ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE),"unknown public key type"},
 {ERR_REASON(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM),"unknown signature algorithm"},
 {ERR_REASON(ASN1_R_UNKNOWN_TAG)          ,"unknown tag"},
-{ERR_REASON(ASN1_R_UNKOWN_FORMAT)        ,"unkown format"},
+{ERR_REASON(ASN1_R_UNKOWN_FORMAT)        ,"unknown format"},
 {ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE),"unsupported any defined by type"},
 {ERR_REASON(ASN1_R_UNSUPPORTED_CIPHER)   ,"unsupported cipher"},
 {ERR_REASON(ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM),"unsupported encryption algorithm"},
diff --git a/src/lib/libcrypto/asn1/x_pubkey.c b/src/lib/libcrypto/asn1/x_pubkey.c
index 627ec87f9f..b649e1fcf9 100644
--- a/src/lib/libcrypto/asn1/x_pubkey.c
+++ b/src/lib/libcrypto/asn1/x_pubkey.c
@@ -175,12 +175,15 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
 	CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
 	if (key->pkey)
 		{
+		CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
 		EVP_PKEY_free(ret);
 		ret = key->pkey;
 		}
 	else
+		{
 		key->pkey = ret;
-	CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
+		CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
+		}
 	CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
 
 	return ret;
diff --git a/src/lib/libcrypto/bio/bss_dgram.c b/src/lib/libcrypto/bio/bss_dgram.c
index 1b1e4bec81..54c012c47d 100644
--- a/src/lib/libcrypto/bio/bss_dgram.c
+++ b/src/lib/libcrypto/bio/bss_dgram.c
@@ -77,10 +77,20 @@
 #define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0
 #endif
 
-#ifdef OPENSSL_SYS_LINUX
+#if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU)
 #define IP_MTU      14 /* linux is lame */
 #endif
 
+#if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED)
+/* Standard definition causes type-punning problems. */
+#undef IN6_IS_ADDR_V4MAPPED
+#define s6_addr32 __u6_addr.__u6_addr32
+#define IN6_IS_ADDR_V4MAPPED(a)               \
+        (((a)->s6_addr32[0] == 0) &&          \
+         ((a)->s6_addr32[1] == 0) &&          \
+         ((a)->s6_addr32[2] == htonl(0x0000ffff)))
+#endif
+
 #ifdef WATT32
 #define sock_write SockWrite  /* Watt-32 uses same names */
 #define sock_read  SockRead
@@ -255,7 +265,7 @@ static void dgram_adjust_rcv_timeout(BIO *b)
 	{
 #if defined(SO_RCVTIMEO)
 	bio_dgram_data *data = (bio_dgram_data *)b->ptr;
-	int sz = sizeof(int);
+	union { size_t s; int i; } sz = {0};
 
 	/* Is a timer active? */
 	if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0)
@@ -265,8 +275,10 @@ static void dgram_adjust_rcv_timeout(BIO *b)
 		/* Read current socket timeout */
 #ifdef OPENSSL_SYS_WINDOWS
 		int timeout;
+
+		sz.i = sizeof(timeout);
 		if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
-					   (void*)&timeout, &sz) < 0)
+					   (void*)&timeout, &sz.i) < 0)
 			{ perror("getsockopt"); }
 		else
 			{
@@ -274,9 +286,12 @@ static void dgram_adjust_rcv_timeout(BIO *b)
 			data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
 			}
 #else
+		sz.i = sizeof(data->socket_timeout);
 		if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 
 						&(data->socket_timeout), (void *)&sz) < 0)
 			{ perror("getsockopt"); }
+		else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0)
+			OPENSSL_assert(sz.s<=sizeof(data->socket_timeout));
 #endif
 
 		/* Get current time */
@@ -445,11 +460,10 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
 	int *ip;
 	struct sockaddr *to = NULL;
 	bio_dgram_data *data = NULL;
-#if defined(IP_MTU_DISCOVER) || defined(IP_MTU)
-	long sockopt_val = 0;
-	unsigned int sockopt_len = 0;
-#endif
-#ifdef OPENSSL_SYS_LINUX
+#if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU))
+	int sockopt_val = 0;
+	socklen_t sockopt_len;	/* assume that system supporting IP_MTU is
+				 * modern enough to define socklen_t */
 	socklen_t addr_len;
 	union	{
 		struct sockaddr	sa;
@@ -531,7 +545,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
 		break;
 		/* (Linux)kernel sets DF bit on outgoing IP packets */
 	case BIO_CTRL_DGRAM_MTU_DISCOVER:
-#ifdef OPENSSL_SYS_LINUX
+#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
 		addr_len = (socklen_t)sizeof(addr);
 		memset((void *)&addr, 0, sizeof(addr));
 		if (getsockname(b->num, &addr.sa, &addr_len) < 0)
@@ -539,7 +553,6 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
 			ret = 0;
 			break;
 			}
-		sockopt_len = sizeof(sockopt_val);
 		switch (addr.sa.sa_family)
 			{
 		case AF_INET:
@@ -548,7 +561,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
 				&sockopt_val, sizeof(sockopt_val))) < 0)
 				perror("setsockopt");
 			break;
-#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER)
+#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
 		case AF_INET6:
 			sockopt_val = IPV6_PMTUDISC_DO;
 			if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
@@ -565,7 +578,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
 		break;
 #endif
 	case BIO_CTRL_DGRAM_QUERY_MTU:
-#ifdef OPENSSL_SYS_LINUX
+#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU)
 		addr_len = (socklen_t)sizeof(addr);
 		memset((void *)&addr, 0, sizeof(addr));
 		if (getsockname(b->num, &addr.sa, &addr_len) < 0)
@@ -727,12 +740,15 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
 #endif
 		break;
 	case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
-#ifdef OPENSSL_SYS_WINDOWS
 		{
-		int timeout, sz = sizeof(timeout);
+		union { size_t s; int i; } sz = {0};
+#ifdef OPENSSL_SYS_WINDOWS
+		int timeout;
 		struct timeval *tv = (struct timeval *)ptr;
+
+		sz.i = sizeof(timeout);
 		if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
-			(void*)&timeout, &sz) < 0)
+			(void*)&timeout, &sz.i) < 0)
 			{ perror("getsockopt"); ret = -1; }
 		else
 			{
@@ -740,12 +756,20 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
 			tv->tv_usec = (timeout % 1000) * 1000;
 			ret = sizeof(*tv);
 			}
-		}
 #else
+		sz.i = sizeof(struct timeval);
 		if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 
-			ptr, (void *)&ret) < 0)
+			ptr, (void *)&sz) < 0)
 			{ perror("getsockopt"); ret = -1; }
+		else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0)
+			{
+			OPENSSL_assert(sz.s<=sizeof(struct timeval));
+			ret = (int)sz.s;
+			}
+		else
+			ret = sz.i;
 #endif
+		}
 		break;
 #endif
 #if defined(SO_SNDTIMEO)
@@ -765,12 +789,15 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
 #endif
 		break;
 	case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
-#ifdef OPENSSL_SYS_WINDOWS
 		{
-		int timeout, sz = sizeof(timeout);
+		union { size_t s; int i; } sz = {0};
+#ifdef OPENSSL_SYS_WINDOWS
+		int timeout;
 		struct timeval *tv = (struct timeval *)ptr;
+
+		sz.i = sizeof(timeout);
 		if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
-			(void*)&timeout, &sz) < 0)
+			(void*)&timeout, &sz.i) < 0)
 			{ perror("getsockopt"); ret = -1; }
 		else
 			{
@@ -778,12 +805,20 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
 			tv->tv_usec = (timeout % 1000) * 1000;
 			ret = sizeof(*tv);
 			}
-		}
 #else
+		sz.i = sizeof(struct timeval);
 		if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, 
-			ptr, (void *)&ret) < 0)
+			ptr, (void *)&sz) < 0)
 			{ perror("getsockopt"); ret = -1; }
+		else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0)
+			{
+			OPENSSL_assert(sz.s<=sizeof(struct timeval));
+			ret = (int)sz.s;
+			}
+		else
+			ret = sz.i;
 #endif
+		}
 		break;
 #endif
 	case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
@@ -871,8 +906,8 @@ BIO *BIO_new_dgram_sctp(int fd, int close_flag)
 	memset(authchunks, 0, sizeof(sockopt_len));
 	ret = getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks, &sockopt_len);
 	OPENSSL_assert(ret >= 0);
-	
-	for (p = (unsigned char*) authchunks + sizeof(sctp_assoc_t);
+
+	for (p = (unsigned char*) authchunks->gauth_chunks;
 	     p < (unsigned char*) authchunks + sockopt_len;
 	     p += sizeof(uint8_t))
 		{
@@ -955,7 +990,6 @@ static int dgram_sctp_free(BIO *a)
 #ifdef SCTP_AUTHENTICATION_EVENT
 void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp)
 	{
-	unsigned int sockopt_len = 0;
 	int ret;
 	struct sctp_authkey_event* authkeyevent = &snp->sn_auth_event;
 
@@ -965,9 +999,8 @@ void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp)
 
 		/* delete key */
 		authkeyid.scact_keynumber = authkeyevent->auth_keynumber;
-		sockopt_len = sizeof(struct sctp_authkeyid);
 		ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
-		      &authkeyid, sockopt_len);
+		      &authkeyid, sizeof(struct sctp_authkeyid));
 		}
 	}
 #endif
@@ -1164,7 +1197,7 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
 			ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS, authchunks, &optlen);
 			OPENSSL_assert(ii >= 0);
 
-			for (p = (unsigned char*) authchunks + sizeof(sctp_assoc_t);
+			for (p = (unsigned char*) authchunks->gauth_chunks;
 				 p < (unsigned char*) authchunks + optlen;
 				 p += sizeof(uint8_t))
 				{
@@ -1298,7 +1331,7 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
 	{
 	long ret=1;
 	bio_dgram_sctp_data *data = NULL;
-	unsigned int sockopt_len = 0;
+	socklen_t sockopt_len = 0;
 	struct sctp_authkeyid authkeyid;
 	struct sctp_authkey *authkey;
 
diff --git a/src/lib/libcrypto/bio/bss_log.c b/src/lib/libcrypto/bio/bss_log.c
index b7dce5c1a2..2227b2b52d 100644
--- a/src/lib/libcrypto/bio/bss_log.c
+++ b/src/lib/libcrypto/bio/bss_log.c
@@ -245,7 +245,7 @@ static int MS_CALLBACK slg_puts(BIO *bp, const char *str)
 
 static void xopenlog(BIO* bp, char* name, int level)
 {
-	if (GetVersion() < 0x80000000)
+	if (check_winnt())
 		bp->ptr = RegisterEventSourceA(NULL,name);
 	else
 		bp->ptr = NULL;
diff --git a/src/lib/libcrypto/bn/asm/mips-mont.pl b/src/lib/libcrypto/bn/asm/mips-mont.pl
index b944a12b8e..caae04ed3a 100644
--- a/src/lib/libcrypto/bn/asm/mips-mont.pl
+++ b/src/lib/libcrypto/bn/asm/mips-mont.pl
@@ -133,7 +133,7 @@ $code.=<<___;
 	bnez	$at,1f
 	li	$t0,0
 	slt	$at,$num,17	# on in-order CPU
-	bnezl	$at,bn_mul_mont_internal
+	bnez	$at,bn_mul_mont_internal
 	nop
 1:	jr	$ra
 	li	$a0,0
diff --git a/src/lib/libcrypto/bn/asm/mips.pl b/src/lib/libcrypto/bn/asm/mips.pl
index c162a3ec23..d2f3ef7bbf 100644
--- a/src/lib/libcrypto/bn/asm/mips.pl
+++ b/src/lib/libcrypto/bn/asm/mips.pl
@@ -140,10 +140,10 @@ $code.=<<___;
 	.set	reorder
 	li	$minus4,-4
 	and	$ta0,$a2,$minus4
-	$LD	$t0,0($a1)
 	beqz	$ta0,.L_bn_mul_add_words_tail
 
 .L_bn_mul_add_words_loop:
+	$LD	$t0,0($a1)
 	$MULTU	$t0,$a3
 	$LD	$t1,0($a0)
 	$LD	$t2,$BNSZ($a1)
@@ -200,10 +200,9 @@ $code.=<<___;
 	$ADDU	$v0,$ta2
 	sltu	$at,$ta3,$at
 	$ST	$ta3,-$BNSZ($a0)
-	$ADDU	$v0,$at
 	.set	noreorder
-	bgtzl	$ta0,.L_bn_mul_add_words_loop
-	$LD	$t0,0($a1)
+	bgtz	$ta0,.L_bn_mul_add_words_loop
+	$ADDU	$v0,$at
 
 	beqz	$a2,.L_bn_mul_add_words_return
 	nop
@@ -300,10 +299,10 @@ $code.=<<___;
 	.set	reorder
 	li	$minus4,-4
 	and	$ta0,$a2,$minus4
-	$LD	$t0,0($a1)
 	beqz	$ta0,.L_bn_mul_words_tail
 
 .L_bn_mul_words_loop:
+	$LD	$t0,0($a1)
 	$MULTU	$t0,$a3
 	$LD	$t2,$BNSZ($a1)
 	$LD	$ta0,2*$BNSZ($a1)
@@ -341,10 +340,9 @@ $code.=<<___;
 	$ADDU	$v0,$at
 	sltu	$ta3,$v0,$at
 	$ST	$v0,-$BNSZ($a0)
-	$ADDU	$v0,$ta3,$ta2
 	.set	noreorder
-	bgtzl	$ta0,.L_bn_mul_words_loop
-	$LD	$t0,0($a1)
+	bgtz	$ta0,.L_bn_mul_words_loop
+	$ADDU	$v0,$ta3,$ta2
 
 	beqz	$a2,.L_bn_mul_words_return
 	nop
@@ -429,10 +427,10 @@ $code.=<<___;
 	.set	reorder
 	li	$minus4,-4
 	and	$ta0,$a2,$minus4
-	$LD	$t0,0($a1)
 	beqz	$ta0,.L_bn_sqr_words_tail
 
 .L_bn_sqr_words_loop:
+	$LD	$t0,0($a1)
 	$MULTU	$t0,$t0
 	$LD	$t2,$BNSZ($a1)
 	$LD	$ta0,2*$BNSZ($a1)
@@ -463,11 +461,10 @@ $code.=<<___;
 	mflo	$ta3
 	mfhi	$ta2
 	$ST	$ta3,-2*$BNSZ($a0)
-	$ST	$ta2,-$BNSZ($a0)
 
 	.set	noreorder
-	bgtzl	$ta0,.L_bn_sqr_words_loop
-	$LD	$t0,0($a1)
+	bgtz	$ta0,.L_bn_sqr_words_loop
+	$ST	$ta2,-$BNSZ($a0)
 
 	beqz	$a2,.L_bn_sqr_words_return
 	nop
@@ -547,10 +544,10 @@ $code.=<<___;
 	.set	reorder
 	li	$minus4,-4
 	and	$at,$a3,$minus4
-	$LD	$t0,0($a1)
 	beqz	$at,.L_bn_add_words_tail
 
 .L_bn_add_words_loop:
+	$LD	$t0,0($a1)
 	$LD	$ta0,0($a2)
 	subu	$a3,4
 	$LD	$t1,$BNSZ($a1)
@@ -589,11 +586,10 @@ $code.=<<___;
 	$ADDU	$t3,$ta3,$v0
 	sltu	$v0,$t3,$ta3
 	$ST	$t3,-$BNSZ($a0)
-	$ADDU	$v0,$t9
 	
 	.set	noreorder
-	bgtzl	$at,.L_bn_add_words_loop
-	$LD	$t0,0($a1)
+	bgtz	$at,.L_bn_add_words_loop
+	$ADDU	$v0,$t9
 
 	beqz	$a3,.L_bn_add_words_return
 	nop
@@ -679,10 +675,10 @@ $code.=<<___;
 	.set	reorder
 	li	$minus4,-4
 	and	$at,$a3,$minus4
-	$LD	$t0,0($a1)
 	beqz	$at,.L_bn_sub_words_tail
 
 .L_bn_sub_words_loop:
+	$LD	$t0,0($a1)
 	$LD	$ta0,0($a2)
 	subu	$a3,4
 	$LD	$t1,$BNSZ($a1)
@@ -722,11 +718,10 @@ $code.=<<___;
 	$SUBU	$t3,$ta3,$v0
 	sgtu	$v0,$t3,$ta3
 	$ST	$t3,-$BNSZ($a0)
-	$ADDU	$v0,$t9
 
 	.set	noreorder
-	bgtzl	$at,.L_bn_sub_words_loop
-	$LD	$t0,0($a1)
+	bgtz	$at,.L_bn_sub_words_loop
+	$ADDU	$v0,$t9
 
 	beqz	$a3,.L_bn_sub_words_return
 	nop
@@ -819,7 +814,7 @@ ___
 $code.=<<___;
 	.set	reorder
 	move	$ta3,$ra
-	bal	bn_div_words
+	bal	bn_div_words_internal
 	move	$ra,$ta3
 	$MULTU	$ta2,$v0
 	$LD	$t2,-2*$BNSZ($a3)
@@ -840,8 +835,9 @@ $code.=<<___;
 	sltu	$ta0,$a1,$a2
 	or	$t8,$ta0
 	.set	noreorder
-	beqzl	$at,.L_bn_div_3_words_inner_loop
+	beqz	$at,.L_bn_div_3_words_inner_loop
 	$SUBU	$v0,1
+	$ADDU	$v0,1
 	.set	reorder
 .L_bn_div_3_words_inner_loop_done:
 	.set	noreorder
@@ -902,7 +898,8 @@ $code.=<<___;
 	and	$t2,$a0
 	$SRL	$at,$a1,$t1
 	.set	noreorder
-	bnezl	$t2,.+8
+	beqz	$t2,.+12
+	nop
 	break	6		# signal overflow
 	.set	reorder
 	$SLL	$a0,$t9
@@ -917,7 +914,8 @@ $code.=<<___;
 	$SRL	$DH,$a2,4*$BNSZ	# bits
 	sgeu	$at,$a0,$a2
 	.set	noreorder
-	bnezl	$at,.+8
+	beqz	$at,.+12
+	nop
 	$SUBU	$a0,$a2
 	.set	reorder
 
diff --git a/src/lib/libcrypto/bn/asm/modexp512-x86_64.pl b/src/lib/libcrypto/bn/asm/modexp512-x86_64.pl
index 54aeb01921..bfd6e97541 100644
--- a/src/lib/libcrypto/bn/asm/modexp512-x86_64.pl
+++ b/src/lib/libcrypto/bn/asm/modexp512-x86_64.pl
@@ -68,7 +68,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 use strict;
 my $code=".text\n\n";
diff --git a/src/lib/libcrypto/bn/asm/parisc-mont.pl b/src/lib/libcrypto/bn/asm/parisc-mont.pl
index 4a766a87fb..c02ef6f014 100644
--- a/src/lib/libcrypto/bn/asm/parisc-mont.pl
+++ b/src/lib/libcrypto/bn/asm/parisc-mont.pl
@@ -40,7 +40,7 @@
 # of arithmetic operations, most notably multiplications. It requires
 # more memory references, most notably to tp[num], but this doesn't
 # seem to exhaust memory port capacity. And indeed, dedicated PA-RISC
-# 2.0 code path, provides virtually same performance as pa-risc2[W].s:
+# 2.0 code path provides virtually same performance as pa-risc2[W].s:
 # it's ~10% better for shortest key length and ~10% worse for longest
 # one.
 #
@@ -988,6 +988,8 @@ foreach (split("\n",$code)) {
 	# assemble 2.0 instructions in 32-bit mode...
 	s/^\s+([a-z]+)([\S]*)\s+([\S]*)/&assemble($1,$2,$3)/e if ($BN_SZ==4);
 
+	s/\bbv\b/bve/gm	if ($SIZE_T==8);
+
 	print $_,"\n";
 }
 close STDOUT;
diff --git a/src/lib/libcrypto/bn/asm/x86_64-gf2m.pl b/src/lib/libcrypto/bn/asm/x86_64-gf2m.pl
index 1658acbbdd..226c66c35e 100644
--- a/src/lib/libcrypto/bn/asm/x86_64-gf2m.pl
+++ b/src/lib/libcrypto/bn/asm/x86_64-gf2m.pl
@@ -31,7 +31,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 ($lo,$hi)=("%rax","%rdx");	$a=$lo;
 ($i0,$i1)=("%rsi","%rdi");
diff --git a/src/lib/libcrypto/bn/asm/x86_64-mont.pl b/src/lib/libcrypto/bn/asm/x86_64-mont.pl
index 5d79b35e1c..17fb94c84c 100755
--- a/src/lib/libcrypto/bn/asm/x86_64-mont.pl
+++ b/src/lib/libcrypto/bn/asm/x86_64-mont.pl
@@ -40,7 +40,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 # int bn_mul_mont(
 $rp="%rdi";	# BN_ULONG *rp,
diff --git a/src/lib/libcrypto/bn/asm/x86_64-mont5.pl b/src/lib/libcrypto/bn/asm/x86_64-mont5.pl
index 057cda28aa..dae0fe2453 100755
--- a/src/lib/libcrypto/bn/asm/x86_64-mont5.pl
+++ b/src/lib/libcrypto/bn/asm/x86_64-mont5.pl
@@ -28,7 +28,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 # int bn_mul_mont_gather5(
 $rp="%rdi";	# BN_ULONG *rp,
@@ -900,8 +901,8 @@ $code.=<<___;
 	jnz	.Lgather
 ___
 $code.=<<___ if ($win64);
-	movaps	%xmm6,(%rsp)
-	movaps	%xmm7,0x10(%rsp)
+	movaps	(%rsp),%xmm6
+	movaps	0x10(%rsp),%xmm7
 	lea	0x28(%rsp),%rsp
 ___
 $code.=<<___;
diff --git a/src/lib/libcrypto/bn/bn.h b/src/lib/libcrypto/bn/bn.h
index f34248ec4f..21a1a3fe35 100644
--- a/src/lib/libcrypto/bn/bn.h
+++ b/src/lib/libcrypto/bn/bn.h
@@ -538,6 +538,8 @@ BIGNUM *BN_mod_inverse(BIGNUM *ret,
 BIGNUM *BN_mod_sqrt(BIGNUM *ret,
 	const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
 
+void	BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords);
+
 /* Deprecated versions */
 #ifndef OPENSSL_NO_DEPRECATED
 BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,
@@ -774,11 +776,20 @@ int RAND_pseudo_bytes(unsigned char *buf,int num);
 
 #define bn_fix_top(a)		bn_check_top(a)
 
+#define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2)
+#define bn_wcheck_size(bn, words) \
+	do { \
+		const BIGNUM *_bnum2 = (bn); \
+		assert(words <= (_bnum2)->dmax && words >= (_bnum2)->top); \
+	} while(0)
+
 #else /* !BN_DEBUG */
 
 #define bn_pollute(a)
 #define bn_check_top(a)
 #define bn_fix_top(a)		bn_correct_top(a)
+#define bn_check_size(bn, bits)
+#define bn_wcheck_size(bn, words)
 
 #endif
 
diff --git a/src/lib/libcrypto/bn/bn_div.c b/src/lib/libcrypto/bn/bn_div.c
index 52b3304293..7b2403185e 100644
--- a/src/lib/libcrypto/bn/bn_div.c
+++ b/src/lib/libcrypto/bn/bn_div.c
@@ -141,6 +141,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
     *
     *					<appro@fy.chalmers.se>
     */
+#undef bn_div_words
 #  define bn_div_words(n0,n1,d0)		\
 	({  asm volatile (			\
 		"divl	%4"			\
@@ -155,6 +156,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
     * Same story here, but it's 128-bit by 64-bit division. Wow!
     *					<appro@fy.chalmers.se>
     */
+#  undef bn_div_words
 #  define bn_div_words(n0,n1,d0)		\
 	({  asm volatile (			\
 		"divq	%4"			\
diff --git a/src/lib/libcrypto/bn/bn_gcd.c b/src/lib/libcrypto/bn/bn_gcd.c
index 4a352119ba..a808f53178 100644
--- a/src/lib/libcrypto/bn/bn_gcd.c
+++ b/src/lib/libcrypto/bn/bn_gcd.c
@@ -205,6 +205,7 @@ err:
 /* solves ax == 1 (mod n) */
 static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in,
         const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
+
 BIGNUM *BN_mod_inverse(BIGNUM *in,
 	const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx)
 	{
diff --git a/src/lib/libcrypto/bn/bn_lcl.h b/src/lib/libcrypto/bn/bn_lcl.h
index eecfd8cc99..817c773b65 100644
--- a/src/lib/libcrypto/bn/bn_lcl.h
+++ b/src/lib/libcrypto/bn/bn_lcl.h
@@ -282,16 +282,23 @@ extern "C" {
 #  endif
 # elif defined(__mips) && (defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG))
 #  if defined(__GNUC__) && __GNUC__>=2
-#   define BN_UMULT_HIGH(a,b)	({	\
+#   if __GNUC__>=4 && __GNUC_MINOR__>=4 /* "h" constraint is no more since 4.4 */
+#     define BN_UMULT_HIGH(a,b)		 (((__uint128_t)(a)*(b))>>64)
+#     define BN_UMULT_LOHI(low,high,a,b) ({	\
+	__uint128_t ret=(__uint128_t)(a)*(b);	\
+	(high)=ret>>64; (low)=ret;	 })
+#   else
+#     define BN_UMULT_HIGH(a,b)	({	\
 	register BN_ULONG ret;		\
 	asm ("dmultu	%1,%2"		\
 	     : "=h"(ret)		\
 	     : "r"(a), "r"(b) : "l");	\
 	ret;			})
-#   define BN_UMULT_LOHI(low,high,a,b)	\
+#     define BN_UMULT_LOHI(low,high,a,b)\
 	asm ("dmultu	%2,%3"		\
 	     : "=l"(low),"=h"(high)	\
 	     : "r"(a), "r"(b));
+#    endif
 #  endif
 # endif		/* cpu */
 #endif		/* OPENSSL_NO_ASM */
diff --git a/src/lib/libcrypto/bn/bn_lib.c b/src/lib/libcrypto/bn/bn_lib.c
index 7a5676de69..5461e6ee7d 100644
--- a/src/lib/libcrypto/bn/bn_lib.c
+++ b/src/lib/libcrypto/bn/bn_lib.c
@@ -824,3 +824,55 @@ int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
 		}
 	return bn_cmp_words(a,b,cl);
 	}
+
+/* 
+ * Constant-time conditional swap of a and b.  
+ * a and b are swapped if condition is not 0.  The code assumes that at most one bit of condition is set.
+ * nwords is the number of words to swap.  The code assumes that at least nwords are allocated in both a and b,
+ * and that no more than nwords are used by either a or b.
+ * a and b cannot be the same number
+ */
+void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
+	{
+	BN_ULONG t;
+	int i;
+
+	bn_wcheck_size(a, nwords);
+	bn_wcheck_size(b, nwords);
+
+	assert(a != b);
+	assert((condition & (condition - 1)) == 0);
+	assert(sizeof(BN_ULONG) >= sizeof(int));
+
+	condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1;
+
+	t = (a->top^b->top) & condition;
+	a->top ^= t;
+	b->top ^= t;
+
+#define BN_CONSTTIME_SWAP(ind) \
+	do { \
+		t = (a->d[ind] ^ b->d[ind]) & condition; \
+		a->d[ind] ^= t; \
+		b->d[ind] ^= t; \
+	} while (0)
+
+
+	switch (nwords) {
+	default:
+		for (i = 10; i < nwords; i++) 
+			BN_CONSTTIME_SWAP(i);
+		/* Fallthrough */
+	case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */
+	case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */
+	case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */
+	case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */
+	case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */
+	case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */
+	case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */
+	case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */
+	case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */
+	case 1: BN_CONSTTIME_SWAP(0);
+	}
+#undef BN_CONSTTIME_SWAP
+}
diff --git a/src/lib/libcrypto/bn/bn_nist.c b/src/lib/libcrypto/bn/bn_nist.c
index 43caee4770..e22968d4a3 100644
--- a/src/lib/libcrypto/bn/bn_nist.c
+++ b/src/lib/libcrypto/bn/bn_nist.c
@@ -286,26 +286,25 @@ const BIGNUM *BN_get0_nist_prime_521(void)
 	}
 
 
-static void nist_cp_bn_0(BN_ULONG *buf, BN_ULONG *a, int top, int max)
+static void nist_cp_bn_0(BN_ULONG *dst, const BN_ULONG *src, int top, int max)
 	{
 	int i;
-	BN_ULONG *_tmp1 = (buf), *_tmp2 = (a);
 
 #ifdef BN_DEBUG
 	OPENSSL_assert(top <= max);
 #endif
-	for (i = (top); i != 0; i--)
-		*_tmp1++ = *_tmp2++;
-	for (i = (max) - (top); i != 0; i--)
-		*_tmp1++ = (BN_ULONG) 0;
+	for (i = 0; i < top; i++)
+		dst[i] = src[i];
+	for (; i < max; i++)
+		dst[i] = 0;
 	}
 
-static void nist_cp_bn(BN_ULONG *buf, BN_ULONG *a, int top)
+static void nist_cp_bn(BN_ULONG *dst, const BN_ULONG *src, int top)
 	{ 
 	int i;
-	BN_ULONG *_tmp1 = (buf), *_tmp2 = (a);
-	for (i = (top); i != 0; i--)
-		*_tmp1++ = *_tmp2++;
+
+	for (i = 0; i < top; i++)
+		dst[i] = src[i];
 	}
 
 #if BN_BITS2 == 64
@@ -451,8 +450,9 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
 	 */
 	mask  = 0-(PTR_SIZE_INT)bn_sub_words(c_d,r_d,_nist_p_192[0],BN_NIST_192_TOP);
 	mask &= 0-(PTR_SIZE_INT)carry;
+	res   = c_d;
 	res   = (BN_ULONG *)
-	 (((PTR_SIZE_INT)c_d&~mask) | ((PTR_SIZE_INT)r_d&mask));
+	 (((PTR_SIZE_INT)res&~mask) | ((PTR_SIZE_INT)r_d&mask));
 	nist_cp_bn(r_d, res, BN_NIST_192_TOP);
 	r->top = BN_NIST_192_TOP;
 	bn_correct_top(r);
@@ -479,8 +479,11 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
 	int	top = a->top, i;
 	int	carry;
 	BN_ULONG *r_d, *a_d = a->d;
-	BN_ULONG buf[BN_NIST_224_TOP],
-		 c_d[BN_NIST_224_TOP],
+	union	{
+		BN_ULONG	bn[BN_NIST_224_TOP];
+		unsigned int	ui[BN_NIST_224_TOP*sizeof(BN_ULONG)/sizeof(unsigned int)];
+		} buf;
+	BN_ULONG c_d[BN_NIST_224_TOP],
 		*res;
 	PTR_SIZE_INT mask;
 	union { bn_addsub_f f; PTR_SIZE_INT p; } u;
@@ -519,18 +522,18 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
 	/* copy upper 256 bits of 448 bit number ... */
 	nist_cp_bn_0(c_d, a_d + (BN_NIST_224_TOP-1), top - (BN_NIST_224_TOP-1), BN_NIST_224_TOP);
 	/* ... and right shift by 32 to obtain upper 224 bits */
-	nist_set_224(buf, c_d, 14, 13, 12, 11, 10, 9, 8);
+	nist_set_224(buf.bn, c_d, 14, 13, 12, 11, 10, 9, 8);
 	/* truncate lower part to 224 bits too */
 	r_d[BN_NIST_224_TOP-1] &= BN_MASK2l;
 #else
-	nist_cp_bn_0(buf, a_d + BN_NIST_224_TOP, top - BN_NIST_224_TOP, BN_NIST_224_TOP);
+	nist_cp_bn_0(buf.bn, a_d + BN_NIST_224_TOP, top - BN_NIST_224_TOP, BN_NIST_224_TOP);
 #endif
 
 #if defined(NIST_INT64) && BN_BITS2!=64
 	{
 	NIST_INT64		acc;	/* accumulator */
 	unsigned int		*rp=(unsigned int *)r_d;
-	const unsigned int	*bp=(const unsigned int *)buf;
+	const unsigned int	*bp=(const unsigned int *)buf.ui;
 
 	acc  = rp[0];	acc -= bp[7-7];
 			acc -= bp[11-7]; rp[0] = (unsigned int)acc; acc >>= 32;
@@ -565,13 +568,13 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
 	{
 	BN_ULONG t_d[BN_NIST_224_TOP];
 
-	nist_set_224(t_d, buf, 10, 9, 8, 7, 0, 0, 0);
+	nist_set_224(t_d, buf.bn, 10, 9, 8, 7, 0, 0, 0);
 	carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
-	nist_set_224(t_d, buf, 0, 13, 12, 11, 0, 0, 0);
+	nist_set_224(t_d, buf.bn, 0, 13, 12, 11, 0, 0, 0);
 	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
-	nist_set_224(t_d, buf, 13, 12, 11, 10, 9, 8, 7);
+	nist_set_224(t_d, buf.bn, 13, 12, 11, 10, 9, 8, 7);
 	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
-	nist_set_224(t_d, buf, 0, 0, 0, 0, 13, 12, 11);
+	nist_set_224(t_d, buf.bn, 0, 0, 0, 0, 13, 12, 11);
 	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
 
 #if BN_BITS2==64
@@ -606,7 +609,8 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
 	/* otherwise it's effectively same as in BN_nist_mod_192... */
 	mask  = 0-(PTR_SIZE_INT)(*u.f)(c_d,r_d,_nist_p_224[0],BN_NIST_224_TOP);
 	mask &= 0-(PTR_SIZE_INT)carry;
-	res   = (BN_ULONG *)(((PTR_SIZE_INT)c_d&~mask) |
+	res   = c_d;
+	res   = (BN_ULONG *)(((PTR_SIZE_INT)res&~mask) |
 	 ((PTR_SIZE_INT)r_d&mask));
 	nist_cp_bn(r_d, res, BN_NIST_224_TOP);
 	r->top = BN_NIST_224_TOP;
@@ -805,7 +809,8 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
 
 	mask  = 0-(PTR_SIZE_INT)(*u.f)(c_d,r_d,_nist_p_256[0],BN_NIST_256_TOP);
 	mask &= 0-(PTR_SIZE_INT)carry;
-	res   = (BN_ULONG *)(((PTR_SIZE_INT)c_d&~mask) |
+	res   = c_d;
+	res   = (BN_ULONG *)(((PTR_SIZE_INT)res&~mask) |
 	 ((PTR_SIZE_INT)r_d&mask));
 	nist_cp_bn(r_d, res, BN_NIST_256_TOP);
 	r->top = BN_NIST_256_TOP;
@@ -1026,7 +1031,8 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
 
 	mask  = 0-(PTR_SIZE_INT)(*u.f)(c_d,r_d,_nist_p_384[0],BN_NIST_384_TOP);
 	mask &= 0-(PTR_SIZE_INT)carry;
-	res   = (BN_ULONG *)(((PTR_SIZE_INT)c_d&~mask) |
+	res   = c_d;
+	res   = (BN_ULONG *)(((PTR_SIZE_INT)res&~mask) |
 	 ((PTR_SIZE_INT)r_d&mask));
 	nist_cp_bn(r_d, res, BN_NIST_384_TOP);
 	r->top = BN_NIST_384_TOP;
@@ -1092,7 +1098,8 @@ int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
 
 	bn_add_words(r_d,r_d,t_d,BN_NIST_521_TOP);
 	mask = 0-(PTR_SIZE_INT)bn_sub_words(t_d,r_d,_nist_p_521,BN_NIST_521_TOP);
-	res  = (BN_ULONG *)(((PTR_SIZE_INT)t_d&~mask) |
+	res  = t_d;
+	res  = (BN_ULONG *)(((PTR_SIZE_INT)res&~mask) |
 	 ((PTR_SIZE_INT)r_d&mask));
 	nist_cp_bn(r_d,res,BN_NIST_521_TOP);
 	r->top = BN_NIST_521_TOP;
diff --git a/src/lib/libcrypto/bn/bn_word.c b/src/lib/libcrypto/bn/bn_word.c
index ee7b87c45c..de83a15b99 100644
--- a/src/lib/libcrypto/bn/bn_word.c
+++ b/src/lib/libcrypto/bn/bn_word.c
@@ -144,26 +144,17 @@ int BN_add_word(BIGNUM *a, BN_ULONG w)
 			a->neg=!(a->neg);
 		return(i);
 		}
-	/* Only expand (and risk failing) if it's possibly necessary */
-	if (((BN_ULONG)(a->d[a->top - 1] + 1) == 0) &&
-			(bn_wexpand(a,a->top+1) == NULL))
-		return(0);
-	i=0;
-	for (;;)
+	for (i=0;w!=0 && i<a->top;i++)
 		{
-		if (i >= a->top)
-			l=w;
-		else
-			l=(a->d[i]+w)&BN_MASK2;
-		a->d[i]=l;
-		if (w > l)
-			w=1;
-		else
-			break;
-		i++;
+		a->d[i] = l = (a->d[i]+w)&BN_MASK2;
+		w = (w>l)?1:0;
 		}
-	if (i >= a->top)
+	if (w && i==a->top)
+		{
+		if (bn_wexpand(a,a->top+1) == NULL) return 0;
 		a->top++;
+		a->d[i]=w;
+		}
 	bn_check_top(a);
 	return(1);
 	}
diff --git a/src/lib/libcrypto/buffer/buffer.c b/src/lib/libcrypto/buffer/buffer.c
index d7aa79ad7f..d4a4ce43b3 100644
--- a/src/lib/libcrypto/buffer/buffer.c
+++ b/src/lib/libcrypto/buffer/buffer.c
@@ -179,14 +179,14 @@ int BUF_MEM_grow_clean(BUF_MEM *str, size_t len)
 	return(len);
 	}
 
-void BUF_reverse(unsigned char *out, unsigned char *in, size_t size)
+void BUF_reverse(unsigned char *out, const unsigned char *in, size_t size)
 	{
 	size_t i;
 	if (in)
 		{
 		out += size - 1;
 		for (i = 0; i < size; i++)
-			*in++ = *out--;
+			*out-- = *in++;
 		}
 	else
 		{
diff --git a/src/lib/libcrypto/buffer/buffer.h b/src/lib/libcrypto/buffer/buffer.h
index 178e418282..f8da32b485 100644
--- a/src/lib/libcrypto/buffer/buffer.h
+++ b/src/lib/libcrypto/buffer/buffer.h
@@ -88,7 +88,7 @@ int	BUF_MEM_grow_clean(BUF_MEM *str, size_t len);
 char *	BUF_strdup(const char *str);
 char *	BUF_strndup(const char *str, size_t siz);
 void *	BUF_memdup(const void *data, size_t siz);
-void	BUF_reverse(unsigned char *out, unsigned char *in, size_t siz);
+void	BUF_reverse(unsigned char *out, const unsigned char *in, size_t siz);
 
 /* safe string functions */
 size_t BUF_strlcpy(char *dst,const char *src,size_t siz);
diff --git a/src/lib/libcrypto/camellia/asm/cmll-x86_64.pl b/src/lib/libcrypto/camellia/asm/cmll-x86_64.pl
index 76955e4726..9f4b82fa48 100644
--- a/src/lib/libcrypto/camellia/asm/cmll-x86_64.pl
+++ b/src/lib/libcrypto/camellia/asm/cmll-x86_64.pl
@@ -40,7 +40,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 sub hi() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1h/;    $r; }
 sub lo() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/;
diff --git a/src/lib/libcrypto/cms/cms_cd.c b/src/lib/libcrypto/cms/cms_cd.c
index a5fc2c4e2b..2021688101 100644
--- a/src/lib/libcrypto/cms/cms_cd.c
+++ b/src/lib/libcrypto/cms/cms_cd.c
@@ -58,7 +58,9 @@
 #include <openssl/err.h>
 #include <openssl/cms.h>
 #include <openssl/bio.h>
+#ifndef OPENSSL_NO_COMP
 #include <openssl/comp.h>
+#endif
 #include "cms_lcl.h"
 
 DECLARE_ASN1_ITEM(CMS_CompressedData)
diff --git a/src/lib/libcrypto/cms/cms_enc.c b/src/lib/libcrypto/cms/cms_enc.c
index f873ce3794..bebeaf29c7 100644
--- a/src/lib/libcrypto/cms/cms_enc.c
+++ b/src/lib/libcrypto/cms/cms_enc.c
@@ -74,7 +74,7 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
 	X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
 	unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL;
 	unsigned char *tkey = NULL;
-	size_t tkeylen;
+	size_t tkeylen = 0;
 
 	int ok = 0;
 
diff --git a/src/lib/libcrypto/cms/cms_lib.c b/src/lib/libcrypto/cms/cms_lib.c
index f88e8f3b52..ba08279a04 100644
--- a/src/lib/libcrypto/cms/cms_lib.c
+++ b/src/lib/libcrypto/cms/cms_lib.c
@@ -411,9 +411,7 @@ int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
 		 * algorithm  OID instead of digest.
 		 */
 			|| EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid)
-			{
 			return EVP_MD_CTX_copy_ex(mctx, mtmp);
-			}
 		chain = BIO_next(chain);
 		}
 	}
@@ -465,8 +463,6 @@ int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert)
 	STACK_OF(CMS_CertificateChoices) **pcerts;
 	int i;
 	pcerts = cms_get0_certificate_choices(cms);
-	if (!pcerts)
-		return 0;
 	if (!pcerts)
 		return 0;
 	for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++)
diff --git a/src/lib/libcrypto/conf/conf_mall.c b/src/lib/libcrypto/conf/conf_mall.c
index c6f4cb2d55..213890e0c2 100644
--- a/src/lib/libcrypto/conf/conf_mall.c
+++ b/src/lib/libcrypto/conf/conf_mall.c
@@ -76,5 +76,6 @@ void OPENSSL_load_builtin_modules(void)
 #ifndef OPENSSL_NO_ENGINE
 	ENGINE_add_conf_module();
 #endif
+	EVP_add_alg_module();
 	}
 
diff --git a/src/lib/libcrypto/cryptlib.c b/src/lib/libcrypto/cryptlib.c
index 766ea8cac7..0b77d8b7d0 100644
--- a/src/lib/libcrypto/cryptlib.c
+++ b/src/lib/libcrypto/cryptlib.c
@@ -504,7 +504,7 @@ void CRYPTO_THREADID_current(CRYPTO_THREADID *id)
 	CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL));
 #else
 	/* For everything else, default to using the address of 'errno' */
-	CRYPTO_THREADID_set_pointer(id, &errno);
+	CRYPTO_THREADID_set_pointer(id, (void*)&errno);
 #endif
 	}
 
@@ -704,6 +704,7 @@ void OPENSSL_cpuid_setup(void)
     }
     else
 	vec = OPENSSL_ia32_cpuid();
+
     /*
      * |(1<<10) sets a reserved bit to signal that variable
      * was initialized already... This is to avoid interference
@@ -888,7 +889,7 @@ void OPENSSL_showfatal (const char *fmta,...)
 
 #if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
     /* this -------------v--- guards NT-specific calls */
-    if (GetVersion() < 0x80000000 && OPENSSL_isservice() > 0)
+    if (check_winnt() && OPENSSL_isservice() > 0)
     {	HANDLE h = RegisterEventSource(0,_T("OPENSSL"));
 	const TCHAR *pmsg=buf;
 	ReportEvent(h,EVENTLOG_ERROR_TYPE,0,0,0,1,0,&pmsg,0);
@@ -924,3 +925,16 @@ void OpenSSLDie(const char *file,int line,const char *assertion)
 	}
 
 void *OPENSSL_stderr(void)	{ return stderr; }
+
+int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len)
+	{
+	size_t i;
+	const unsigned char *a = in_a;
+	const unsigned char *b = in_b;
+	unsigned char x = 0;
+
+	for (i = 0; i < len; i++)
+		x |= a[i] ^ b[i];
+
+	return x;
+	}
diff --git a/src/lib/libcrypto/cryptlib.h b/src/lib/libcrypto/cryptlib.h
index 1761f6b668..d26f9630ea 100644
--- a/src/lib/libcrypto/cryptlib.h
+++ b/src/lib/libcrypto/cryptlib.h
@@ -100,7 +100,7 @@ extern "C" {
 
 void OPENSSL_cpuid_setup(void);
 extern unsigned int OPENSSL_ia32cap_P[];
-void OPENSSL_showfatal(const char *,...);
+void OPENSSL_showfatal(const char *fmta,...);
 void *OPENSSL_stderr(void);
 extern int OPENSSL_NONPIC_relocated;
 
diff --git a/src/lib/libcrypto/crypto.h b/src/lib/libcrypto/crypto.h
index 6aeda0a9ac..f92fc5182d 100644
--- a/src/lib/libcrypto/crypto.h
+++ b/src/lib/libcrypto/crypto.h
@@ -488,10 +488,10 @@ void CRYPTO_get_mem_debug_functions(void (**m)(void *,int,const char *,int,int),
 				    long (**go)(void));
 
 void *CRYPTO_malloc_locked(int num, const char *file, int line);
-void CRYPTO_free_locked(void *);
+void CRYPTO_free_locked(void *ptr);
 void *CRYPTO_malloc(int num, const char *file, int line);
 char *CRYPTO_strdup(const char *str, const char *file, int line);
-void CRYPTO_free(void *);
+void CRYPTO_free(void *ptr);
 void *CRYPTO_realloc(void *addr,int num, const char *file, int line);
 void *CRYPTO_realloc_clean(void *addr,int old_num,int num,const char *file,
 			   int line);
@@ -574,6 +574,13 @@ void OPENSSL_init(void);
 #define fips_cipher_abort(alg) while(0)
 #endif
 
+/* CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. It
+ * takes an amount of time dependent on |len|, but independent of the contents
+ * of |a| and |b|. Unlike memcmp, it cannot be used to put elements into a
+ * defined order as the return value when a != b is undefined, other than to be
+ * non-zero. */
+int CRYPTO_memcmp(const void *a, const void *b, size_t len);
+
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
  * made after this point may be overwritten when the script is next run.
diff --git a/src/lib/libcrypto/des/set_key.c b/src/lib/libcrypto/des/set_key.c
index d3e69ca8b5..da4d62e112 100644
--- a/src/lib/libcrypto/des/set_key.c
+++ b/src/lib/libcrypto/des/set_key.c
@@ -63,9 +63,8 @@
  * 1.1 added norm_expand_bits
  * 1.0 First working version
  */
-#include "des_locl.h"
-
 #include <openssl/crypto.h>
+#include "des_locl.h"
 
 OPENSSL_IMPLEMENT_GLOBAL(int,DES_check_key,0)	/* defaults to false */
 
diff --git a/src/lib/libcrypto/des/str2key.c b/src/lib/libcrypto/des/str2key.c
index 9c2054bda6..1077f99d1b 100644
--- a/src/lib/libcrypto/des/str2key.c
+++ b/src/lib/libcrypto/des/str2key.c
@@ -56,8 +56,8 @@
  * [including the GNU Public Licence.]
  */
 
-#include "des_locl.h"
 #include <openssl/crypto.h>
+#include "des_locl.h"
 
 void DES_string_to_key(const char *str, DES_cblock *key)
 	{
diff --git a/src/lib/libcrypto/doc/ERR_get_error.pod b/src/lib/libcrypto/doc/ERR_get_error.pod
index 34443045fc..828ecf529b 100644
--- a/src/lib/libcrypto/doc/ERR_get_error.pod
+++ b/src/lib/libcrypto/doc/ERR_get_error.pod
@@ -52,8 +52,11 @@ ERR_get_error_line_data(), ERR_peek_error_line_data() and
 ERR_get_last_error_line_data() store additional data and flags
 associated with the error code in *B<data>
 and *B<flags>, unless these are B<NULL>. *B<data> contains a string
-if *B<flags>&B<ERR_TXT_STRING>. If it has been allocated by OPENSSL_malloc(),
-*B<flags>&B<ERR_TXT_MALLOCED> is true.
+if *B<flags>&B<ERR_TXT_STRING> is true. 
+
+An application B<MUST NOT> free the *B<data> pointer (or any other pointers
+returned by these functions) with OPENSSL_free() as freeing is handled
+automatically by the error library.
 
 =head1 RETURN VALUES
 
diff --git a/src/lib/libcrypto/doc/EVP_BytesToKey.pod b/src/lib/libcrypto/doc/EVP_BytesToKey.pod
index d375c46e03..0ea7d55c0f 100644
--- a/src/lib/libcrypto/doc/EVP_BytesToKey.pod
+++ b/src/lib/libcrypto/doc/EVP_BytesToKey.pod
@@ -17,7 +17,7 @@ EVP_BytesToKey - password based encryption routine
 
 EVP_BytesToKey() derives a key and IV from various parameters. B<type> is
 the cipher to derive the key and IV for. B<md> is the message digest to use.
-The B<salt> paramter is used as a salt in the derivation: it should point to
+The B<salt> parameter is used as a salt in the derivation: it should point to
 an 8 byte buffer or NULL if no salt is used. B<data> is a buffer containing
 B<datal> bytes which is used to derive the keying data. B<count> is the
 iteration count to use. The derived key and IV will be written to B<key>
diff --git a/src/lib/libcrypto/doc/EVP_EncryptInit.pod b/src/lib/libcrypto/doc/EVP_EncryptInit.pod
index 8271d3dfc4..1c4bf184a1 100644
--- a/src/lib/libcrypto/doc/EVP_EncryptInit.pod
+++ b/src/lib/libcrypto/doc/EVP_EncryptInit.pod
@@ -152,7 +152,7 @@ does not remain in memory.
 
 EVP_EncryptInit(), EVP_DecryptInit() and EVP_CipherInit() behave in a
 similar way to EVP_EncryptInit_ex(), EVP_DecryptInit_ex and
-EVP_CipherInit_ex() except the B<ctx> paramter does not need to be
+EVP_CipherInit_ex() except the B<ctx> parameter does not need to be
 initialized and they always use the default cipher implementation.
 
 EVP_EncryptFinal(), EVP_DecryptFinal() and EVP_CipherFinal() behave in a
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_CTX_ctrl.pod b/src/lib/libcrypto/doc/EVP_PKEY_CTX_ctrl.pod
index f2f455990f..13b91f1e6e 100644
--- a/src/lib/libcrypto/doc/EVP_PKEY_CTX_ctrl.pod
+++ b/src/lib/libcrypto/doc/EVP_PKEY_CTX_ctrl.pod
@@ -117,7 +117,7 @@ L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
 L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
 L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
 L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
 L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
 L<EVP_PKEY_keygen(3)|EVP_PKEY_keygen(3)> 
 
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_decrypt.pod b/src/lib/libcrypto/doc/EVP_PKEY_decrypt.pod
index 42b2a8c44e..847983237b 100644
--- a/src/lib/libcrypto/doc/EVP_PKEY_decrypt.pod
+++ b/src/lib/libcrypto/doc/EVP_PKEY_decrypt.pod
@@ -83,7 +83,7 @@ L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
 L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
 L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
 L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
 L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
 
 =head1 HISTORY
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_derive.pod b/src/lib/libcrypto/doc/EVP_PKEY_derive.pod
index d9d6d76c72..27464be571 100644
--- a/src/lib/libcrypto/doc/EVP_PKEY_derive.pod
+++ b/src/lib/libcrypto/doc/EVP_PKEY_derive.pod
@@ -84,7 +84,7 @@ L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
 L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
 L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
 L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
 
 =head1 HISTORY
 
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_encrypt.pod b/src/lib/libcrypto/doc/EVP_PKEY_encrypt.pod
index 91c9c5d0a5..e495a81242 100644
--- a/src/lib/libcrypto/doc/EVP_PKEY_encrypt.pod
+++ b/src/lib/libcrypto/doc/EVP_PKEY_encrypt.pod
@@ -83,7 +83,7 @@ L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
 L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
 L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
 L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
 L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
 
 =head1 HISTORY
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_get_default_digest.pod b/src/lib/libcrypto/doc/EVP_PKEY_get_default_digest.pod
index 1a9c7954c5..8ff597d44a 100644
--- a/src/lib/libcrypto/doc/EVP_PKEY_get_default_digest.pod
+++ b/src/lib/libcrypto/doc/EVP_PKEY_get_default_digest.pod
@@ -32,7 +32,7 @@ public key algorithm.
 L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
 L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
 L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
 
 =head1 HISTORY
 
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_keygen.pod b/src/lib/libcrypto/doc/EVP_PKEY_keygen.pod
index 37c6fe9503..fd431ace6d 100644
--- a/src/lib/libcrypto/doc/EVP_PKEY_keygen.pod
+++ b/src/lib/libcrypto/doc/EVP_PKEY_keygen.pod
@@ -151,7 +151,7 @@ L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
 L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
 L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
 L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
 L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
 
 =head1 HISTORY
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_sign.pod b/src/lib/libcrypto/doc/EVP_PKEY_sign.pod
index 2fb52c3486..a044f2c131 100644
--- a/src/lib/libcrypto/doc/EVP_PKEY_sign.pod
+++ b/src/lib/libcrypto/doc/EVP_PKEY_sign.pod
@@ -86,7 +86,7 @@ L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
 L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
 L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
 L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
 L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
 
 =head1 HISTORY
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_verify.pod b/src/lib/libcrypto/doc/EVP_PKEY_verify.pod
index f93e5fc6c3..90612ba2f0 100644
--- a/src/lib/libcrypto/doc/EVP_PKEY_verify.pod
+++ b/src/lib/libcrypto/doc/EVP_PKEY_verify.pod
@@ -81,7 +81,7 @@ L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
 L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
 L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
 L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
-L<EVP_PKEY_verifyrecover(3)|EVP_PKEY_verifyrecover(3)>,
+L<EVP_PKEY_verify_recover(3)|EVP_PKEY_verify_recover(3)>,
 L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
 
 =head1 HISTORY
diff --git a/src/lib/libcrypto/doc/EVP_PKEY_verify_recover.pod b/src/lib/libcrypto/doc/EVP_PKEY_verify_recover.pod
new file mode 100644
index 0000000000..23a28a9c43
--- /dev/null
+++ b/src/lib/libcrypto/doc/EVP_PKEY_verify_recover.pod
@@ -0,0 +1,103 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_verify_recover_init, EVP_PKEY_verify_recover - recover signature using a public key algorithm
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx);
+ int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx,
+			unsigned char *rout, size_t *routlen,
+			const unsigned char *sig, size_t siglen);
+
+=head1 DESCRIPTION
+
+The EVP_PKEY_verify_recover_init() function initializes a public key algorithm
+context using key B<pkey> for a verify recover operation.
+
+The EVP_PKEY_verify_recover() function recovers signed data
+using B<ctx>. The signature is specified using the B<sig> and
+B<siglen> parameters. If B<rout> is B<NULL> then the maximum size of the output
+buffer is written to the B<routlen> parameter. If B<rout> is not B<NULL> then
+before the call the B<routlen> parameter should contain the length of the
+B<rout> buffer, if the call is successful recovered data is written to
+B<rout> and the amount of data written to B<routlen>.
+
+=head1 NOTES
+
+Normally an application is only interested in whether a signature verification
+operation is successful in those cases the EVP_verify() function should be 
+used.
+
+Sometimes however it is useful to obtain the data originally signed using a
+signing operation. Only certain public key algorithms can recover a signature
+in this way (for example RSA in PKCS padding mode).
+
+After the call to EVP_PKEY_verify_recover_init() algorithm specific control
+operations can be performed to set any appropriate parameters for the
+operation.
+
+The function EVP_PKEY_verify_recover() can be called more than once on the same
+context if several operations are performed using the same parameters.
+
+=head1 RETURN VALUES
+
+EVP_PKEY_verify_recover_init() and EVP_PKEY_verify_recover() return 1 for success
+and 0 or a negative value for failure. In particular a return value of -2
+indicates the operation is not supported by the public key algorithm.
+
+=head1 EXAMPLE
+
+Recover digest originally signed using PKCS#1 and SHA256 digest:
+
+ #include <openssl/evp.h>
+ #include <openssl/rsa.h>
+
+ EVP_PKEY_CTX *ctx;
+ unsigned char *rout, *sig;
+ size_t routlen, siglen; 
+ EVP_PKEY *verify_key;
+ /* NB: assumes verify_key, sig and siglen are already set up
+  * and that verify_key is an RSA public key
+  */
+ ctx = EVP_PKEY_CTX_new(verify_key);
+ if (!ctx)
+	/* Error occurred */
+ if (EVP_PKEY_verify_recover_init(ctx) <= 0)
+	/* Error */
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
+	/* Error */
+ if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha256()) <= 0)
+	/* Error */
+
+ /* Determine buffer length */
+ if (EVP_PKEY_verify_recover(ctx, NULL, &routlen, sig, siglen) <= 0)
+	/* Error */
+
+ rout = OPENSSL_malloc(routlen);
+
+ if (!rout)
+	/* malloc failure */
+ 
+ if (EVP_PKEY_verify_recover(ctx, rout, &routlen, sig, siglen) <= 0)
+	/* Error */
+
+ /* Recovered data is routlen bytes written to buffer rout */
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_CTX_new(3)|EVP_PKEY_CTX_new(3)>,
+L<EVP_PKEY_encrypt(3)|EVP_PKEY_encrypt(3)>,
+L<EVP_PKEY_decrypt(3)|EVP_PKEY_decrypt(3)>,
+L<EVP_PKEY_sign(3)|EVP_PKEY_sign(3)>,
+L<EVP_PKEY_verify(3)|EVP_PKEY_verify(3)>,
+L<EVP_PKEY_derive(3)|EVP_PKEY_derive(3)> 
+
+=head1 HISTORY
+
+These functions were first added to OpenSSL 1.0.0.
+
+=cut
diff --git a/src/lib/libcrypto/doc/X509_STORE_CTX_get_error.pod b/src/lib/libcrypto/doc/X509_STORE_CTX_get_error.pod
index a883f6c097..60e8332ae9 100644
--- a/src/lib/libcrypto/doc/X509_STORE_CTX_get_error.pod
+++ b/src/lib/libcrypto/doc/X509_STORE_CTX_get_error.pod
@@ -278,6 +278,8 @@ happen if extended CRL checking is enabled.
 an application specific error. This will never be returned unless explicitly
 set by an application.
 
+=back
+
 =head1 NOTES
 
 The above functions should be used instead of directly referencing the fields
diff --git a/src/lib/libcrypto/doc/X509_VERIFY_PARAM_set_flags.pod b/src/lib/libcrypto/doc/X509_VERIFY_PARAM_set_flags.pod
index b68eece033..46cac2bea2 100644
--- a/src/lib/libcrypto/doc/X509_VERIFY_PARAM_set_flags.pod
+++ b/src/lib/libcrypto/doc/X509_VERIFY_PARAM_set_flags.pod
@@ -113,7 +113,7 @@ a special status code is set to the verification callback. This permits it
 to examine the valid policy tree and perform additional checks or simply
 log it for debugging purposes.
 
-By default some addtional features such as indirect CRLs and CRLs signed by
+By default some additional features such as indirect CRLs and CRLs signed by
 different keys are disabled. If B<X509_V_FLAG_EXTENDED_CRL_SUPPORT> is set
 they are enabled.
 
diff --git a/src/lib/libcrypto/ec/ec.h b/src/lib/libcrypto/ec/ec.h
index 9d01325af3..dfe8710d33 100644
--- a/src/lib/libcrypto/ec/ec.h
+++ b/src/lib/libcrypto/ec/ec.h
@@ -274,10 +274,10 @@ int EC_GROUP_get_curve_name(const EC_GROUP *group);
 void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
 int EC_GROUP_get_asn1_flag(const EC_GROUP *group);
 
-void EC_GROUP_set_point_conversion_form(EC_GROUP *, point_conversion_form_t);
+void EC_GROUP_set_point_conversion_form(EC_GROUP *group, point_conversion_form_t form);
 point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
 
-unsigned char *EC_GROUP_get0_seed(const EC_GROUP *);
+unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x);
 size_t EC_GROUP_get_seed_len(const EC_GROUP *);
 size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
 
@@ -626,8 +626,8 @@ int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *c
  */
 int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
 
-int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
-int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
+int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx);
+int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx);
 
 /** Computes r = generator * n sum_{i=0}^num p[i] * m[i]
  *  \param  group  underlying EC_GROUP object
@@ -800,16 +800,24 @@ const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
 int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
 
 unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
-void EC_KEY_set_enc_flags(EC_KEY *, unsigned int);
-point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *);
-void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t);
+void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags);
+point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key);
+void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform);
 /* functions to set/get method specific data  */
-void *EC_KEY_get_key_method_data(EC_KEY *, 
+void *EC_KEY_get_key_method_data(EC_KEY *key, 
 	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
-void EC_KEY_insert_key_method_data(EC_KEY *, void *data,
+/** Sets the key method data of an EC_KEY object, if none has yet been set.
+ *  \param  key              EC_KEY object
+ *  \param  data             opaque data to install.
+ *  \param  dup_func         a function that duplicates |data|.
+ *  \param  free_func        a function that frees |data|.
+ *  \param  clear_free_func  a function that wipes and frees |data|.
+ *  \return the previously set data pointer, or NULL if |data| was inserted.
+ */
+void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
 	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
 /* wrapper functions for the underlying EC_GROUP object */
-void EC_KEY_set_asn1_flag(EC_KEY *, int);
+void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag);
 
 /** Creates a table of pre-computed multiples of the generator to 
  *  accelerate further EC_KEY operations.
diff --git a/src/lib/libcrypto/ec/ec2_mult.c b/src/lib/libcrypto/ec/ec2_mult.c
index 26f4a783fc..1c575dc47a 100644
--- a/src/lib/libcrypto/ec/ec2_mult.c
+++ b/src/lib/libcrypto/ec/ec2_mult.c
@@ -208,11 +208,15 @@ static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, BIG
 	return ret;
 	}
 
+
 /* Computes scalar*point and stores the result in r.
  * point can not equal r.
- * Uses algorithm 2P of
+ * Uses a modified algorithm 2P of
  *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over 
  *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
+ *
+ * To protect against side-channel attack the function uses constant time swap,
+ * avoiding conditional branches.
  */
 static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
 	const EC_POINT *point, BN_CTX *ctx)
@@ -246,6 +250,11 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r,
 	x2 = &r->X;
 	z2 = &r->Y;
 
+	bn_wexpand(x1, group->field.top);
+	bn_wexpand(z1, group->field.top);
+	bn_wexpand(x2, group->field.top);
+	bn_wexpand(z2, group->field.top);
+
 	if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */
 	if (!BN_one(z1)) goto err; /* z1 = 1 */
 	if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */
@@ -270,16 +279,12 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r,
 		word = scalar->d[i];
 		while (mask)
 			{
-			if (word & mask)
-				{
-				if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err;
-				if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err;
-				}
-			else
-				{
-				if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err;
-				if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err;
-				}
+			BN_consttime_swap(word & mask, x1, x2, group->field.top);
+			BN_consttime_swap(word & mask, z1, z2, group->field.top);
+			if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err;
+			if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err;
+			BN_consttime_swap(word & mask, x1, x2, group->field.top);
+			BN_consttime_swap(word & mask, z1, z2, group->field.top);
 			mask >>= 1;
 			}
 		mask = BN_TBIT;
diff --git a/src/lib/libcrypto/ec/ec_ameth.c b/src/lib/libcrypto/ec/ec_ameth.c
index 83909c1853..0ce4524076 100644
--- a/src/lib/libcrypto/ec/ec_ameth.c
+++ b/src/lib/libcrypto/ec/ec_ameth.c
@@ -88,7 +88,7 @@ static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
 		if (!pstr)
 			return 0;
 		pstr->length = i2d_ECParameters(ec_key, &pstr->data);
-		if (pstr->length < 0)
+		if (pstr->length <= 0)
 			{
 			ASN1_STRING_free(pstr);
 			ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
diff --git a/src/lib/libcrypto/ec/ec_asn1.c b/src/lib/libcrypto/ec/ec_asn1.c
index 175eec5342..145807b611 100644
--- a/src/lib/libcrypto/ec/ec_asn1.c
+++ b/src/lib/libcrypto/ec/ec_asn1.c
@@ -89,7 +89,8 @@ int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
 	if (group == NULL)
 		return 0;
 
-	if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve
+	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
+	    NID_X9_62_characteristic_two_field
 	    || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] == 0)))
 		{
 		ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
@@ -107,7 +108,8 @@ int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
 	if (group == NULL)
 		return 0;
 
-	if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve
+	if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
+	    NID_X9_62_characteristic_two_field
 	    || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] != 0) && (group->poly[3] != 0) && (group->poly[4] == 0)))
 		{
 		ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
diff --git a/src/lib/libcrypto/ec/ec_key.c b/src/lib/libcrypto/ec/ec_key.c
index bf9fd2dc2c..7fa247593d 100644
--- a/src/lib/libcrypto/ec/ec_key.c
+++ b/src/lib/libcrypto/ec/ec_key.c
@@ -520,18 +520,27 @@ void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
 void *EC_KEY_get_key_method_data(EC_KEY *key,
 	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
 	{
-	return EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
+	void *ret;
+
+	CRYPTO_r_lock(CRYPTO_LOCK_EC);
+	ret = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
+	CRYPTO_r_unlock(CRYPTO_LOCK_EC);
+
+	return ret;
 	}
 
-void EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
+void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
 	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
 	{
 	EC_EXTRA_DATA *ex_data;
+
 	CRYPTO_w_lock(CRYPTO_LOCK_EC);
 	ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
 	if (ex_data == NULL)
 		EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func);
 	CRYPTO_w_unlock(CRYPTO_LOCK_EC);
+
+	return ex_data;
 	}
 
 void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
index 25247b5803..de9a0cc2b3 100644
--- a/src/lib/libcrypto/ec/ec_lib.c
+++ b/src/lib/libcrypto/ec/ec_lib.c
@@ -480,10 +480,10 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
 	if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
 	    EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
 		return 1;
-	/* compare the curve name (if present) */
+	/* compare the curve name (if present in both) */
 	if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
-	    EC_GROUP_get_curve_name(a) == EC_GROUP_get_curve_name(b))
-		return 0;
+	    EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
+		return 1;
 
 	if (!ctx)
 		ctx_new = ctx = BN_CTX_new();
@@ -993,12 +993,12 @@ int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN
 	if (group->meth->point_cmp == 0)
 		{
 		ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
-		return 0;
+		return -1;
 		}
 	if ((group->meth != a->meth) || (a->meth != b->meth))
 		{
 		ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
-		return 0;
+		return -1;
 		}
 	return group->meth->point_cmp(group, a, b, ctx);
 	}
diff --git a/src/lib/libcrypto/ec/ec_pmeth.c b/src/lib/libcrypto/ec/ec_pmeth.c
index d1ed66c37e..66ee397d86 100644
--- a/src/lib/libcrypto/ec/ec_pmeth.c
+++ b/src/lib/libcrypto/ec/ec_pmeth.c
@@ -188,7 +188,7 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
 
 	pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
 
-	/* NB: unlike PKS#3 DH, if *outlen is less than maximum size this is
+	/* NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is
 	 * not an error, the result is truncated.
 	 */
 
diff --git a/src/lib/libcrypto/ec/ecp_mont.c b/src/lib/libcrypto/ec/ecp_mont.c
index 079e47431b..f04f132c7a 100644
--- a/src/lib/libcrypto/ec/ecp_mont.c
+++ b/src/lib/libcrypto/ec/ecp_mont.c
@@ -114,7 +114,6 @@ const EC_METHOD *EC_GFp_mont_method(void)
 		ec_GFp_mont_field_decode,
 		ec_GFp_mont_field_set_to_one };
 
-
 	return &ret;
 #endif
 	}
diff --git a/src/lib/libcrypto/ecdh/ech_key.c b/src/lib/libcrypto/ecdh/ech_key.c
index f44da9298b..2988899ea2 100644
--- a/src/lib/libcrypto/ecdh/ech_key.c
+++ b/src/lib/libcrypto/ecdh/ech_key.c
@@ -68,9 +68,6 @@
  */
 
 #include "ech_locl.h"
-#ifndef OPENSSL_NO_ENGINE
-#include <openssl/engine.h>
-#endif
 
 int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
 	EC_KEY *eckey,
diff --git a/src/lib/libcrypto/ecdh/ech_lib.c b/src/lib/libcrypto/ecdh/ech_lib.c
index dadbfd3c49..0644431b75 100644
--- a/src/lib/libcrypto/ecdh/ech_lib.c
+++ b/src/lib/libcrypto/ecdh/ech_lib.c
@@ -222,8 +222,15 @@ ECDH_DATA *ecdh_check(EC_KEY *key)
 		ecdh_data = (ECDH_DATA *)ecdh_data_new();
 		if (ecdh_data == NULL)
 			return NULL;
-		EC_KEY_insert_key_method_data(key, (void *)ecdh_data,
-			ecdh_data_dup, ecdh_data_free, ecdh_data_free);
+		data = EC_KEY_insert_key_method_data(key, (void *)ecdh_data,
+			   ecdh_data_dup, ecdh_data_free, ecdh_data_free);
+		if (data != NULL)
+			{
+			/* Another thread raced us to install the key_method
+			 * data and won. */
+			ecdh_data_free(ecdh_data);
+			ecdh_data = (ECDH_DATA *)data;
+			}
 	}
 	else
 		ecdh_data = (ECDH_DATA *)data;
diff --git a/src/lib/libcrypto/ecdsa/ecs_lib.c b/src/lib/libcrypto/ecdsa/ecs_lib.c
index e477da430b..814a6bf404 100644
--- a/src/lib/libcrypto/ecdsa/ecs_lib.c
+++ b/src/lib/libcrypto/ecdsa/ecs_lib.c
@@ -200,8 +200,15 @@ ECDSA_DATA *ecdsa_check(EC_KEY *key)
 		ecdsa_data = (ECDSA_DATA *)ecdsa_data_new();
 		if (ecdsa_data == NULL)
 			return NULL;
-		EC_KEY_insert_key_method_data(key, (void *)ecdsa_data,
-			ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free);
+		data = EC_KEY_insert_key_method_data(key, (void *)ecdsa_data,
+			   ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free);
+		if (data != NULL)
+			{
+			/* Another thread raced us to install the key_method
+			 * data and won. */
+			ecdsa_data_free(ecdsa_data);
+			ecdsa_data = (ECDSA_DATA *)data;
+			}
 	}
 	else
 		ecdsa_data = (ECDSA_DATA *)data;
diff --git a/src/lib/libcrypto/engine/eng_list.c b/src/lib/libcrypto/engine/eng_list.c
index 27846edb1e..95c858960b 100644
--- a/src/lib/libcrypto/engine/eng_list.c
+++ b/src/lib/libcrypto/engine/eng_list.c
@@ -408,6 +408,7 @@ ENGINE *ENGINE_by_id(const char *id)
 				!ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) ||
 				!ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
 					load_dir, 0) ||
+				!ENGINE_ctrl_cmd_string(iterator, "LIST_ADD", "1", 0) ||
 				!ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
 				goto notfound;
 		return iterator;
diff --git a/src/lib/libcrypto/err/err_all.c b/src/lib/libcrypto/err/err_all.c
index bd8946d8ba..8eb547d98d 100644
--- a/src/lib/libcrypto/err/err_all.c
+++ b/src/lib/libcrypto/err/err_all.c
@@ -64,7 +64,9 @@
 #endif
 #include <openssl/buffer.h>
 #include <openssl/bio.h>
+#ifndef OPENSSL_NO_COMP
 #include <openssl/comp.h>
+#endif
 #ifndef OPENSSL_NO_RSA
 #include <openssl/rsa.h>
 #endif
@@ -95,6 +97,9 @@
 #include <openssl/ui.h>
 #include <openssl/ocsp.h>
 #include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
 #include <openssl/ts.h>
 #ifndef OPENSSL_NO_CMS
 #include <openssl/cms.h>
@@ -102,11 +107,6 @@
 #ifndef OPENSSL_NO_JPAKE
 #include <openssl/jpake.h>
 #endif
-#include <openssl/comp.h>
-
-#ifdef OPENSSL_FIPS
-#include <openssl/fips.h>
-#endif
 
 void ERR_load_crypto_strings(void)
 	{
@@ -130,7 +130,9 @@ void ERR_load_crypto_strings(void)
 	ERR_load_ASN1_strings();
 	ERR_load_CONF_strings();
 	ERR_load_CRYPTO_strings();
+#ifndef OPENSSL_NO_COMP
 	ERR_load_COMP_strings();
+#endif
 #ifndef OPENSSL_NO_EC
 	ERR_load_EC_strings();
 #endif
@@ -153,15 +155,14 @@ void ERR_load_crypto_strings(void)
 #endif
 	ERR_load_OCSP_strings();
 	ERR_load_UI_strings();
+#ifdef OPENSSL_FIPS
+	ERR_load_FIPS_strings();
+#endif
 #ifndef OPENSSL_NO_CMS
 	ERR_load_CMS_strings();
 #endif
 #ifndef OPENSSL_NO_JPAKE
 	ERR_load_JPAKE_strings();
 #endif
-	ERR_load_COMP_strings();
-#endif
-#ifdef OPENSSL_FIPS
-	ERR_load_FIPS_strings();
 #endif
 	}
diff --git a/src/lib/libcrypto/evp/bio_b64.c b/src/lib/libcrypto/evp/bio_b64.c
index 72a2a67277..ac6d441aad 100644
--- a/src/lib/libcrypto/evp/bio_b64.c
+++ b/src/lib/libcrypto/evp/bio_b64.c
@@ -264,7 +264,7 @@ static int b64_read(BIO *b, char *out, int outl)
 				}
 
 			/* we fell off the end without starting */
-			if (j == i)
+			if ((j == i) && (num == 0))
 				{
 				/* Is this is one long chunk?, if so, keep on
 				 * reading until a new line. */
diff --git a/src/lib/libcrypto/evp/digest.c b/src/lib/libcrypto/evp/digest.c
index 467e6b5ae9..d14e8e48d5 100644
--- a/src/lib/libcrypto/evp/digest.c
+++ b/src/lib/libcrypto/evp/digest.c
@@ -267,6 +267,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
 	return FIPS_digestfinal(ctx, md, size);
 #else
 	int ret;
+
 	OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
 	ret=ctx->digest->final(ctx,md);
 	if (size != NULL)
@@ -365,8 +366,11 @@ int EVP_Digest(const void *data, size_t count,
 
 void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
 	{
-	EVP_MD_CTX_cleanup(ctx);
-	OPENSSL_free(ctx);
+	if (ctx)
+		{
+		EVP_MD_CTX_cleanup(ctx);
+		OPENSSL_free(ctx);
+		}
 	}
 
 /* This call frees resources associated with the context */
diff --git a/src/lib/libcrypto/evp/e_aes.c b/src/lib/libcrypto/evp/e_aes.c
index 1e4af0cb75..c7869b69ef 100644
--- a/src/lib/libcrypto/evp/e_aes.c
+++ b/src/lib/libcrypto/evp/e_aes.c
@@ -842,7 +842,10 @@ static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
 			gctx->ctr = NULL;
 			break;
 			}
+		else
 #endif
+		(void)0;	/* terminate potentially open 'else' */
+
 		AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks);
 		CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f)AES_encrypt);
 #ifdef AES_CTR_ASM
@@ -969,8 +972,6 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 
 	if (!gctx->iv_set)
 		return -1;
-	if (!ctx->encrypt && gctx->taglen < 0)
-		return -1;
 	if (in)
 		{
 		if (out == NULL)
@@ -1012,6 +1013,8 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 		{
 		if (!ctx->encrypt)
 			{
+			if (gctx->taglen < 0)
+				return -1;
 			if (CRYPTO_gcm128_finish(&gctx->gcm,
 					ctx->buf, gctx->taglen) != 0)
 				return -1;
@@ -1083,14 +1086,17 @@ static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
 			xctx->xts.block1 = (block128_f)vpaes_decrypt;
 			}
 
-		vpaes_set_encrypt_key(key + ctx->key_len/2,
+		    vpaes_set_encrypt_key(key + ctx->key_len/2,
 						ctx->key_len * 4, &xctx->ks2);
-		xctx->xts.block2 = (block128_f)vpaes_encrypt;
+		    xctx->xts.block2 = (block128_f)vpaes_encrypt;
 
-		xctx->xts.key1 = &xctx->ks1;
-		break;
-		}
+		    xctx->xts.key1 = &xctx->ks1;
+		    break;
+		    }
+		else
 #endif
+		(void)0;	/* terminate potentially open 'else' */
+
 		if (enc)
 			{
 			AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1);
@@ -1217,6 +1223,7 @@ static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
 			vpaes_set_encrypt_key(key, ctx->key_len*8, &cctx->ks);
 			CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
 					&cctx->ks, (block128_f)vpaes_encrypt);
+			cctx->str = NULL;
 			cctx->key_set = 1;
 			break;
 			}
diff --git a/src/lib/libcrypto/evp/e_aes_cbc_hmac_sha1.c b/src/lib/libcrypto/evp/e_aes_cbc_hmac_sha1.c
index 710fb79baf..fb2c884a78 100644
--- a/src/lib/libcrypto/evp/e_aes_cbc_hmac_sha1.c
+++ b/src/lib/libcrypto/evp/e_aes_cbc_hmac_sha1.c
@@ -1,5 +1,5 @@
 /* ====================================================================
- * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 2011-2013 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
@@ -90,6 +90,10 @@ typedef struct
 	defined(_M_AMD64)	|| defined(_M_X64)	|| \
 	defined(__INTEL__)	)
 
+#if defined(__GNUC__) && __GNUC__>=2 && !defined(PEDANTIC)
+# define BSWAP(x) ({ unsigned int r=(x); asm ("bswapl %0":"=r"(r):"0"(r)); r; })
+#endif
+
 extern unsigned int OPENSSL_ia32cap_P[2];
 #define AESNI_CAPABLE   (1<<(57-32))
 
@@ -167,6 +171,9 @@ static void sha1_update(SHA_CTX *c,const void *data,size_t len)
 		SHA1_Update(c,ptr,res);
 }
 
+#ifdef SHA1_Update
+#undef SHA1_Update
+#endif
 #define SHA1_Update sha1_update
 
 static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
@@ -184,6 +191,8 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 	sha_off = SHA_CBLOCK-key->md.num;
 #endif
 
+	key->payload_length = NO_PAYLOAD_LENGTH;
+
 	if (len%AES_BLOCK_SIZE) return 0;
 
 	if (ctx->encrypt) {
@@ -234,47 +243,211 @@ static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 					&key->ks,ctx->iv,1);
 		}
 	} else {
-		unsigned char mac[SHA_DIGEST_LENGTH];
+		union { unsigned int  u[SHA_DIGEST_LENGTH/sizeof(unsigned int)];
+			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,
 				&key->ks,ctx->iv,0);
 
 		if (plen) {	/* "TLS" mode of operation */
-			/* figure out payload length */
-			if (len<(size_t)(out[len-1]+1+SHA_DIGEST_LENGTH))
-				return 0;
-
-			len -= (out[len-1]+1+SHA_DIGEST_LENGTH);
+			size_t inp_len, mask, j, i;
+			unsigned int res, maxpad, pad, bitlen;
+			int ret = 1;
+			union {	unsigned int  u[SHA_LBLOCK];
+				unsigned char c[SHA_CBLOCK]; }
+				*data = (void *)key->md.data;
 
 			if ((key->aux.tls_aad[plen-4]<<8|key->aux.tls_aad[plen-3])
-			    >= TLS1_1_VERSION) {
-				len -= AES_BLOCK_SIZE;
+			    >= TLS1_1_VERSION)
 				iv = AES_BLOCK_SIZE;
-			}
 
-			key->aux.tls_aad[plen-2] = len>>8;
-			key->aux.tls_aad[plen-1] = len;
+			if (len<(iv+SHA_DIGEST_LENGTH+1))
+				return 0;
+
+			/* omit explicit iv */
+			out += iv;
+			len -= iv;
+
+			/* figure out payload length */
+			pad = out[len-1];
+			maxpad = len-(SHA_DIGEST_LENGTH+1);
+			maxpad |= (255-maxpad)>>(sizeof(maxpad)*8-8);
+			maxpad &= 255;
+
+			inp_len = len - (SHA_DIGEST_LENGTH+pad+1);
+			mask = (0-((inp_len-len)>>(sizeof(inp_len)*8-1)));
+			inp_len &= mask;
+			ret &= (int)mask;
+
+			key->aux.tls_aad[plen-2] = inp_len>>8;
+			key->aux.tls_aad[plen-1] = inp_len;
 
-			/* calculate HMAC and verify it */
+			/* calculate HMAC */
 			key->md = key->head;
 			SHA1_Update(&key->md,key->aux.tls_aad,plen);
-			SHA1_Update(&key->md,out+iv,len);
-			SHA1_Final(mac,&key->md);
 
+#if 1
+			len -= SHA_DIGEST_LENGTH;		/* amend mac */
+			if (len>=(256+SHA_CBLOCK)) {
+				j = (len-(256+SHA_CBLOCK))&(0-SHA_CBLOCK);
+				j += SHA_CBLOCK-key->md.num;
+				SHA1_Update(&key->md,out,j);
+				out += j;
+				len -= j;
+				inp_len -= j;
+			}
+
+			/* 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
+
+			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];
+				mask = (j-inp_len)>>(sizeof(j)*8-8);
+				c &= mask;
+				c |= 0x80&~mask&~((inp_len-j)>>(sizeof(j)*8-8));
+				data->c[res++]=(unsigned char)c;
+
+				if (res!=SHA_CBLOCK) continue;
+
+				/* j is not incremented yet */
+				mask = 0-((inp_len+7-j)>>(sizeof(j)*8-1));
+				data->u[SHA_LBLOCK-1] |= bitlen&mask;
+				sha1_block_data_order(&key->md,data,1);
+				mask &= 0-((j-inp_len-72)>>(sizeof(j)*8-1));
+				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;
+			}
+
+			for(i=res;i<SHA_CBLOCK;i++,j++) data->c[i]=0;
+
+			if (res>SHA_CBLOCK-8) {
+				mask = 0-((inp_len+8-j)>>(sizeof(j)*8-1));
+				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));
+				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;
+			}
+			data->u[SHA_LBLOCK-1] = bitlen;
+			sha1_block_data_order(&key->md,data,1);
+			mask = 0-((j-inp_len-73)>>(sizeof(j)*8-1));
+			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
+			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 = 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(pmac->c,&key->md);
+
+			{
+			unsigned int inp_blocks, pad_blocks;
+
+			/* but pretend as if we hashed padded payload */
+			inp_blocks = 1+((SHA_CBLOCK-9-res)>>(sizeof(res)*8-1));
+			res += (unsigned int)(len-inp_len);
+			pad_blocks = res / SHA_CBLOCK;
+			res %= SHA_CBLOCK;
+			pad_blocks += 1+((SHA_CBLOCK-9-res)>>(sizeof(res)*8-1));
+			for (;inp_blocks<pad_blocks;inp_blocks++)
+				sha1_block_data_order(&key->md,data,1);
+			}
+#endif
 			key->md = key->tail;
-			SHA1_Update(&key->md,mac,SHA_DIGEST_LENGTH);
-			SHA1_Final(mac,&key->md);
+			SHA1_Update(&key->md,pmac->c,SHA_DIGEST_LENGTH);
+			SHA1_Final(pmac->c,&key->md);
 
-			if (memcmp(out+iv+len,mac,SHA_DIGEST_LENGTH))
-				return 0;
+			/* verify HMAC */
+			out += inp_len;
+			len -= inp_len;
+#if 1
+			{
+			unsigned char *p = out+len-1-maxpad-SHA_DIGEST_LENGTH;
+			size_t off = out-p;
+			unsigned int c, cmask;
+
+			maxpad += SHA_DIGEST_LENGTH;
+			for (res=0,i=0,j=0;j<maxpad;j++) {
+				c = p[j];
+				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^pmac->c[i])&cmask;
+				i += 1&cmask;
+			}
+			maxpad -= SHA_DIGEST_LENGTH;
+
+			res = 0-((0-res)>>(sizeof(res)*8-1));
+			ret &= (int)~res;
+			}
+#else
+			for (res=0,i=0;i<SHA_DIGEST_LENGTH;i++)
+				res |= out[i]^pmac->c[i];
+			res = 0-((0-res)>>(sizeof(res)*8-1));
+			ret &= (int)~res;
+
+			/* verify padding */
+			pad = (pad&~res) | (maxpad&res);
+			out = out+len-1-pad;
+			for (res=0,i=0;i<pad;i++)
+				res |= out[i]^pad;
+
+			res = (0-res)>>(sizeof(res)*8-1);
+			ret &= (int)~res;
+#endif
+			return ret;
 		} else {
 			SHA1_Update(&key->md,out,len);
 		}
 	}
 
-	key->payload_length = NO_PAYLOAD_LENGTH;
-
 	return 1;
 	}
 
@@ -309,6 +482,8 @@ static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void
 		SHA1_Init(&key->tail);
 		SHA1_Update(&key->tail,hmac_key,sizeof(hmac_key));
 
+		OPENSSL_cleanse(hmac_key,sizeof(hmac_key));
+
 		return 1;
 		}
 	case EVP_CTRL_AEAD_TLS1_AAD:
diff --git a/src/lib/libcrypto/evp/e_des3.c b/src/lib/libcrypto/evp/e_des3.c
index 1e69972662..8d7b7de292 100644
--- a/src/lib/libcrypto/evp/e_des3.c
+++ b/src/lib/libcrypto/evp/e_des3.c
@@ -101,7 +101,7 @@ static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 			      const unsigned char *in, size_t inl)
 {
-	if (inl>=EVP_MAXCHUNK)
+	while (inl>=EVP_MAXCHUNK)
 		{
 		DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK,
 			       &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
@@ -132,7 +132,7 @@ static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 	printf("\n");
 	}
 #endif    /* KSSL_DEBUG */
-	if (inl>=EVP_MAXCHUNK)
+	while (inl>=EVP_MAXCHUNK)
 		{
 		DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK,
 			     &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
@@ -151,7 +151,7 @@ static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 			      const unsigned char *in, size_t inl)
 {
-	if (inl>=EVP_MAXCHUNK)
+	while (inl>=EVP_MAXCHUNK)
 		{
 		DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, 
 			       &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 0d1b20a7d3..faeb3c24e6 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -402,7 +402,6 @@ struct evp_cipher_st
 /* Length of tag for TLS */
 #define EVP_GCM_TLS_TAG_LEN				16
 
-
 typedef struct evp_cipher_info_st
 	{
 	const EVP_CIPHER *cipher;
@@ -789,8 +788,8 @@ const EVP_CIPHER *EVP_aes_128_cfb128(void);
 # define EVP_aes_128_cfb EVP_aes_128_cfb128
 const EVP_CIPHER *EVP_aes_128_ofb(void);
 const EVP_CIPHER *EVP_aes_128_ctr(void);
-const EVP_CIPHER *EVP_aes_128_gcm(void);
 const EVP_CIPHER *EVP_aes_128_ccm(void);
+const EVP_CIPHER *EVP_aes_128_gcm(void);
 const EVP_CIPHER *EVP_aes_128_xts(void);
 const EVP_CIPHER *EVP_aes_192_ecb(void);
 const EVP_CIPHER *EVP_aes_192_cbc(void);
@@ -800,8 +799,8 @@ const EVP_CIPHER *EVP_aes_192_cfb128(void);
 # define EVP_aes_192_cfb EVP_aes_192_cfb128
 const EVP_CIPHER *EVP_aes_192_ofb(void);
 const EVP_CIPHER *EVP_aes_192_ctr(void);
-const EVP_CIPHER *EVP_aes_192_gcm(void);
 const EVP_CIPHER *EVP_aes_192_ccm(void);
+const EVP_CIPHER *EVP_aes_192_gcm(void);
 const EVP_CIPHER *EVP_aes_256_ecb(void);
 const EVP_CIPHER *EVP_aes_256_cbc(void);
 const EVP_CIPHER *EVP_aes_256_cfb1(void);
@@ -810,8 +809,8 @@ const EVP_CIPHER *EVP_aes_256_cfb128(void);
 # define EVP_aes_256_cfb EVP_aes_256_cfb128
 const EVP_CIPHER *EVP_aes_256_ofb(void);
 const EVP_CIPHER *EVP_aes_256_ctr(void);
-const EVP_CIPHER *EVP_aes_256_gcm(void);
 const EVP_CIPHER *EVP_aes_256_ccm(void);
+const EVP_CIPHER *EVP_aes_256_gcm(void);
 const EVP_CIPHER *EVP_aes_256_xts(void);
 #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
 const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void);
@@ -1243,6 +1242,8 @@ void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
 	int (*ctrl_str)(EVP_PKEY_CTX *ctx,
 					const char *type, const char *value));
 
+void EVP_add_alg_module(void);
+
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
  * made after this point may be overwritten when the script is next run.
@@ -1257,6 +1258,7 @@ void ERR_load_EVP_strings(void);
 #define EVP_F_AES_INIT_KEY				 133
 #define EVP_F_AES_XTS					 172
 #define EVP_F_AES_XTS_CIPHER				 175
+#define EVP_F_ALG_MODULE_INIT				 177
 #define EVP_F_CAMELLIA_INIT_KEY				 159
 #define EVP_F_CMAC_INIT					 173
 #define EVP_F_D2I_PKEY					 100
@@ -1350,15 +1352,19 @@ void ERR_load_EVP_strings(void);
 #define EVP_R_DIFFERENT_PARAMETERS			 153
 #define EVP_R_DISABLED_FOR_FIPS				 163
 #define EVP_R_ENCODE_ERROR				 115
+#define EVP_R_ERROR_LOADING_SECTION			 165
+#define EVP_R_ERROR_SETTING_FIPS_MODE			 166
 #define EVP_R_EVP_PBE_CIPHERINIT_ERROR			 119
 #define EVP_R_EXPECTING_AN_RSA_KEY			 127
 #define EVP_R_EXPECTING_A_DH_KEY			 128
 #define EVP_R_EXPECTING_A_DSA_KEY			 129
 #define EVP_R_EXPECTING_A_ECDSA_KEY			 141
 #define EVP_R_EXPECTING_A_EC_KEY			 142
+#define EVP_R_FIPS_MODE_NOT_SUPPORTED			 167
 #define EVP_R_INITIALIZATION_ERROR			 134
 #define EVP_R_INPUT_NOT_INITIALIZED			 111
 #define EVP_R_INVALID_DIGEST				 152
+#define EVP_R_INVALID_FIPS_MODE				 168
 #define EVP_R_INVALID_KEY_LENGTH			 130
 #define EVP_R_INVALID_OPERATION				 148
 #define EVP_R_IV_TOO_LARGE				 102
@@ -1383,6 +1389,7 @@ void ERR_load_EVP_strings(void);
 #define EVP_R_TOO_LARGE					 164
 #define EVP_R_UNKNOWN_CIPHER				 160
 #define EVP_R_UNKNOWN_DIGEST				 161
+#define EVP_R_UNKNOWN_OPTION				 169
 #define EVP_R_UNKNOWN_PBE_ALGORITHM			 121
 #define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS		 135
 #define EVP_R_UNSUPPORTED_ALGORITHM			 156
diff --git a/src/lib/libcrypto/evp/evp_err.c b/src/lib/libcrypto/evp/evp_err.c
index db0f76d59b..08eab9882f 100644
--- a/src/lib/libcrypto/evp/evp_err.c
+++ b/src/lib/libcrypto/evp/evp_err.c
@@ -75,6 +75,7 @@ static ERR_STRING_DATA EVP_str_functs[]=
 {ERR_FUNC(EVP_F_AES_INIT_KEY),	"AES_INIT_KEY"},
 {ERR_FUNC(EVP_F_AES_XTS),	"AES_XTS"},
 {ERR_FUNC(EVP_F_AES_XTS_CIPHER),	"AES_XTS_CIPHER"},
+{ERR_FUNC(EVP_F_ALG_MODULE_INIT),	"ALG_MODULE_INIT"},
 {ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY),	"CAMELLIA_INIT_KEY"},
 {ERR_FUNC(EVP_F_CMAC_INIT),	"CMAC_INIT"},
 {ERR_FUNC(EVP_F_D2I_PKEY),	"D2I_PKEY"},
@@ -171,15 +172,19 @@ static ERR_STRING_DATA EVP_str_reasons[]=
 {ERR_REASON(EVP_R_DIFFERENT_PARAMETERS)  ,"different parameters"},
 {ERR_REASON(EVP_R_DISABLED_FOR_FIPS)     ,"disabled for fips"},
 {ERR_REASON(EVP_R_ENCODE_ERROR)          ,"encode error"},
+{ERR_REASON(EVP_R_ERROR_LOADING_SECTION) ,"error loading section"},
+{ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE),"error setting fips mode"},
 {ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR),"evp pbe cipherinit error"},
 {ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY)  ,"expecting an rsa key"},
 {ERR_REASON(EVP_R_EXPECTING_A_DH_KEY)    ,"expecting a dh key"},
 {ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY)   ,"expecting a dsa key"},
 {ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY) ,"expecting a ecdsa key"},
 {ERR_REASON(EVP_R_EXPECTING_A_EC_KEY)    ,"expecting a ec key"},
+{ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED),"fips mode not supported"},
 {ERR_REASON(EVP_R_INITIALIZATION_ERROR)  ,"initialization error"},
 {ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) ,"input not initialized"},
 {ERR_REASON(EVP_R_INVALID_DIGEST)        ,"invalid digest"},
+{ERR_REASON(EVP_R_INVALID_FIPS_MODE)     ,"invalid fips mode"},
 {ERR_REASON(EVP_R_INVALID_KEY_LENGTH)    ,"invalid key length"},
 {ERR_REASON(EVP_R_INVALID_OPERATION)     ,"invalid operation"},
 {ERR_REASON(EVP_R_IV_TOO_LARGE)          ,"iv too large"},
@@ -204,6 +209,7 @@ static ERR_STRING_DATA EVP_str_reasons[]=
 {ERR_REASON(EVP_R_TOO_LARGE)             ,"too large"},
 {ERR_REASON(EVP_R_UNKNOWN_CIPHER)        ,"unknown cipher"},
 {ERR_REASON(EVP_R_UNKNOWN_DIGEST)        ,"unknown digest"},
+{ERR_REASON(EVP_R_UNKNOWN_OPTION)        ,"unknown option"},
 {ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"},
 {ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"},
 {ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM) ,"unsupported algorithm"},
diff --git a/src/lib/libcrypto/evp/m_dss.c b/src/lib/libcrypto/evp/m_dss.c
index 4ad63ada6f..6fb7e9a861 100644
--- a/src/lib/libcrypto/evp/m_dss.c
+++ b/src/lib/libcrypto/evp/m_dss.c
@@ -60,7 +60,7 @@
 #include "cryptlib.h"
 #include <openssl/evp.h>
 #include <openssl/objects.h>
-#include <openssl/x509.h>
+#include <openssl/sha.h>
 #ifndef OPENSSL_NO_DSA
 #include <openssl/dsa.h>
 #endif
diff --git a/src/lib/libcrypto/evp/m_dss1.c b/src/lib/libcrypto/evp/m_dss1.c
index f80170efeb..2df362a670 100644
--- a/src/lib/libcrypto/evp/m_dss1.c
+++ b/src/lib/libcrypto/evp/m_dss1.c
@@ -63,7 +63,7 @@
 
 #include <openssl/evp.h>
 #include <openssl/objects.h>
-#include <openssl/x509.h>
+#include <openssl/sha.h>
 #ifndef OPENSSL_NO_DSA
 #include <openssl/dsa.h>
 #endif
diff --git a/src/lib/libcrypto/evp/m_sha1.c b/src/lib/libcrypto/evp/m_sha1.c
index 3cb11f1ebb..bd0c01ad3c 100644
--- a/src/lib/libcrypto/evp/m_sha1.c
+++ b/src/lib/libcrypto/evp/m_sha1.c
@@ -65,7 +65,7 @@
 
 #include <openssl/evp.h>
 #include <openssl/objects.h>
-#include <openssl/x509.h>
+#include <openssl/sha.h>
 #ifndef OPENSSL_NO_RSA
 #include <openssl/rsa.h>
 #endif
diff --git a/src/lib/libcrypto/evp/p5_crpt2.c b/src/lib/libcrypto/evp/p5_crpt2.c
index 975d004df4..fe3c6c8813 100644
--- a/src/lib/libcrypto/evp/p5_crpt2.c
+++ b/src/lib/libcrypto/evp/p5_crpt2.c
@@ -85,19 +85,24 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
 	unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
 	int cplen, j, k, tkeylen, mdlen;
 	unsigned long i = 1;
-	HMAC_CTX hctx;
+	HMAC_CTX hctx_tpl, hctx;
 
 	mdlen = EVP_MD_size(digest);
 	if (mdlen < 0)
 		return 0;
 
-	HMAC_CTX_init(&hctx);
+	HMAC_CTX_init(&hctx_tpl);
 	p = out;
 	tkeylen = keylen;
 	if(!pass)
 		passlen = 0;
 	else if(passlen == -1)
 		passlen = strlen(pass);
+	if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL))
+		{
+		HMAC_CTX_cleanup(&hctx_tpl);
+		return 0;
+		}
 	while(tkeylen)
 		{
 		if(tkeylen > mdlen)
@@ -111,19 +116,36 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
 		itmp[1] = (unsigned char)((i >> 16) & 0xff);
 		itmp[2] = (unsigned char)((i >> 8) & 0xff);
 		itmp[3] = (unsigned char)(i & 0xff);
-		if (!HMAC_Init_ex(&hctx, pass, passlen, digest, NULL)
-			|| !HMAC_Update(&hctx, salt, saltlen)
-			|| !HMAC_Update(&hctx, itmp, 4)
-			|| !HMAC_Final(&hctx, digtmp, NULL))
+		if (!HMAC_CTX_copy(&hctx, &hctx_tpl))
 			{
+			HMAC_CTX_cleanup(&hctx_tpl);
+			return 0;
+			}
+		if (!HMAC_Update(&hctx, salt, saltlen)
+		    || !HMAC_Update(&hctx, itmp, 4)
+		    || !HMAC_Final(&hctx, digtmp, NULL))
+			{
+			HMAC_CTX_cleanup(&hctx_tpl);
 			HMAC_CTX_cleanup(&hctx);
 			return 0;
 			}
+		HMAC_CTX_cleanup(&hctx);
 		memcpy(p, digtmp, cplen);
 		for(j = 1; j < iter; j++)
 			{
-			HMAC(digest, pass, passlen,
-				 digtmp, mdlen, digtmp, NULL);
+			if (!HMAC_CTX_copy(&hctx, &hctx_tpl))
+				{
+				HMAC_CTX_cleanup(&hctx_tpl);
+				return 0;
+				}
+			if (!HMAC_Update(&hctx, digtmp, mdlen)
+			    || !HMAC_Final(&hctx, digtmp, NULL))
+				{
+				HMAC_CTX_cleanup(&hctx_tpl);
+				HMAC_CTX_cleanup(&hctx);
+				return 0;
+				}
+			HMAC_CTX_cleanup(&hctx);
 			for(k = 0; k < cplen; k++)
 				p[k] ^= digtmp[k];
 			}
@@ -131,7 +153,7 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
 		i++;
 		p+= cplen;
 		}
-	HMAC_CTX_cleanup(&hctx);
+	HMAC_CTX_cleanup(&hctx_tpl);
 #ifdef DEBUG_PKCS5V2
 	fprintf(stderr, "Password:\n");
 	h__dump (pass, passlen);
diff --git a/src/lib/libcrypto/evp/p_sign.c b/src/lib/libcrypto/evp/p_sign.c
index dfa48c157c..8afb664306 100644
--- a/src/lib/libcrypto/evp/p_sign.c
+++ b/src/lib/libcrypto/evp/p_sign.c
@@ -80,7 +80,7 @@ int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
 	{
 	unsigned char m[EVP_MAX_MD_SIZE];
 	unsigned int m_len;
-	int i=0,ok=0,v;
+	int i = 0,ok = 0,v;
 	EVP_MD_CTX tmp_ctx;
 	EVP_PKEY_CTX *pkctx = NULL;
 
diff --git a/src/lib/libcrypto/evp/p_verify.c b/src/lib/libcrypto/evp/p_verify.c
index 5f5c409f45..c66d63ccf8 100644
--- a/src/lib/libcrypto/evp/p_verify.c
+++ b/src/lib/libcrypto/evp/p_verify.c
@@ -67,7 +67,7 @@ int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf,
 	{
 	unsigned char m[EVP_MAX_MD_SIZE];
 	unsigned int m_len;
-	int i=-1,ok=0,v;
+	int i = 0,ok = 0,v;
 	EVP_MD_CTX tmp_ctx;
 	EVP_PKEY_CTX *pkctx = NULL;
 
diff --git a/src/lib/libcrypto/md4/md4_dgst.c b/src/lib/libcrypto/md4/md4_dgst.c
index 82c2cb2d98..b5b165b052 100644
--- a/src/lib/libcrypto/md4/md4_dgst.c
+++ b/src/lib/libcrypto/md4/md4_dgst.c
@@ -106,22 +106,23 @@ void md4_block_data_order (MD4_CTX *c, const void *data_, size_t num)
 
 	for (;num--;)
 		{
-	HOST_c2l(data,l); X( 0)=l;		HOST_c2l(data,l); X( 1)=l;
+	(void)HOST_c2l(data,l); X( 0)=l;
+	(void)HOST_c2l(data,l); X( 1)=l;
 	/* Round 0 */
-	R0(A,B,C,D,X( 0), 3,0);	HOST_c2l(data,l); X( 2)=l;
-	R0(D,A,B,C,X( 1), 7,0);	HOST_c2l(data,l); X( 3)=l;
-	R0(C,D,A,B,X( 2),11,0);	HOST_c2l(data,l); X( 4)=l;
-	R0(B,C,D,A,X( 3),19,0);	HOST_c2l(data,l); X( 5)=l;
-	R0(A,B,C,D,X( 4), 3,0);	HOST_c2l(data,l); X( 6)=l;
-	R0(D,A,B,C,X( 5), 7,0);	HOST_c2l(data,l); X( 7)=l;
-	R0(C,D,A,B,X( 6),11,0);	HOST_c2l(data,l); X( 8)=l;
-	R0(B,C,D,A,X( 7),19,0);	HOST_c2l(data,l); X( 9)=l;
-	R0(A,B,C,D,X( 8), 3,0);	HOST_c2l(data,l); X(10)=l;
-	R0(D,A,B,C,X( 9), 7,0);	HOST_c2l(data,l); X(11)=l;
-	R0(C,D,A,B,X(10),11,0);	HOST_c2l(data,l); X(12)=l;
-	R0(B,C,D,A,X(11),19,0);	HOST_c2l(data,l); X(13)=l;
-	R0(A,B,C,D,X(12), 3,0);	HOST_c2l(data,l); X(14)=l;
-	R0(D,A,B,C,X(13), 7,0);	HOST_c2l(data,l); X(15)=l;
+	R0(A,B,C,D,X( 0), 3,0);	(void)HOST_c2l(data,l); X( 2)=l;
+	R0(D,A,B,C,X( 1), 7,0);	(void)HOST_c2l(data,l); X( 3)=l;
+	R0(C,D,A,B,X( 2),11,0);	(void)HOST_c2l(data,l); X( 4)=l;
+	R0(B,C,D,A,X( 3),19,0);	(void)HOST_c2l(data,l); X( 5)=l;
+	R0(A,B,C,D,X( 4), 3,0);	(void)HOST_c2l(data,l); X( 6)=l;
+	R0(D,A,B,C,X( 5), 7,0);	(void)HOST_c2l(data,l); X( 7)=l;
+	R0(C,D,A,B,X( 6),11,0);	(void)HOST_c2l(data,l); X( 8)=l;
+	R0(B,C,D,A,X( 7),19,0);	(void)HOST_c2l(data,l); X( 9)=l;
+	R0(A,B,C,D,X( 8), 3,0);	(void)HOST_c2l(data,l); X(10)=l;
+	R0(D,A,B,C,X( 9), 7,0);	(void)HOST_c2l(data,l); X(11)=l;
+	R0(C,D,A,B,X(10),11,0);	(void)HOST_c2l(data,l); X(12)=l;
+	R0(B,C,D,A,X(11),19,0);	(void)HOST_c2l(data,l); X(13)=l;
+	R0(A,B,C,D,X(12), 3,0);	(void)HOST_c2l(data,l); X(14)=l;
+	R0(D,A,B,C,X(13), 7,0);	(void)HOST_c2l(data,l); X(15)=l;
 	R0(C,D,A,B,X(14),11,0);
 	R0(B,C,D,A,X(15),19,0);
 	/* Round 1 */
diff --git a/src/lib/libcrypto/md4/md4_locl.h b/src/lib/libcrypto/md4/md4_locl.h
index c8085b0ead..99c3e5004c 100644
--- a/src/lib/libcrypto/md4/md4_locl.h
+++ b/src/lib/libcrypto/md4/md4_locl.h
@@ -77,10 +77,10 @@ void md4_block_data_order (MD4_CTX *c, const void *p,size_t num);
 #define HASH_FINAL		MD4_Final
 #define	HASH_MAKE_STRING(c,s)	do {	\
 	unsigned long ll;		\
-	ll=(c)->A; HOST_l2c(ll,(s));	\
-	ll=(c)->B; HOST_l2c(ll,(s));	\
-	ll=(c)->C; HOST_l2c(ll,(s));	\
-	ll=(c)->D; HOST_l2c(ll,(s));	\
+	ll=(c)->A; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->B; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->C; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->D; (void)HOST_l2c(ll,(s));	\
 	} while (0)
 #define	HASH_BLOCK_DATA_ORDER	md4_block_data_order
 
diff --git a/src/lib/libcrypto/md5/asm/md5-x86_64.pl b/src/lib/libcrypto/md5/asm/md5-x86_64.pl
index 867885435e..f11224d172 100755
--- a/src/lib/libcrypto/md5/asm/md5-x86_64.pl
+++ b/src/lib/libcrypto/md5/asm/md5-x86_64.pl
@@ -120,7 +120,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
 die "can't locate x86_64-xlate.pl";
 
 no warnings qw(uninitialized);
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 $code .= <<EOF;
 .text
diff --git a/src/lib/libcrypto/md5/md5_locl.h b/src/lib/libcrypto/md5/md5_locl.h
index 968d577995..74d63d1f9c 100644
--- a/src/lib/libcrypto/md5/md5_locl.h
+++ b/src/lib/libcrypto/md5/md5_locl.h
@@ -86,10 +86,10 @@ void md5_block_data_order (MD5_CTX *c, const void *p,size_t num);
 #define HASH_FINAL		MD5_Final
 #define	HASH_MAKE_STRING(c,s)	do {	\
 	unsigned long ll;		\
-	ll=(c)->A; HOST_l2c(ll,(s));	\
-	ll=(c)->B; HOST_l2c(ll,(s));	\
-	ll=(c)->C; HOST_l2c(ll,(s));	\
-	ll=(c)->D; HOST_l2c(ll,(s));	\
+	ll=(c)->A; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->B; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->C; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->D; (void)HOST_l2c(ll,(s));	\
 	} while (0)
 #define	HASH_BLOCK_DATA_ORDER	md5_block_data_order
 
diff --git a/src/lib/libcrypto/modes/asm/ghash-alpha.pl b/src/lib/libcrypto/modes/asm/ghash-alpha.pl
index 6358b2750f..aa36029386 100644
--- a/src/lib/libcrypto/modes/asm/ghash-alpha.pl
+++ b/src/lib/libcrypto/modes/asm/ghash-alpha.pl
@@ -266,8 +266,8 @@ gcm_gmult_4bit:
 	ldq	$Xlo,8($Xi)
 	ldq	$Xhi,0($Xi)
 
-	br	$rem_4bit,.Lpic1
-.Lpic1:	lda	$rem_4bit,rem_4bit-.Lpic1($rem_4bit)
+	bsr	$t0,picmeup
+	nop
 ___
 
 	&loop();
@@ -341,8 +341,8 @@ gcm_ghash_4bit:
 	ldq	$Xhi,0($Xi)
 	ldq	$Xlo,8($Xi)
 
-	br	$rem_4bit,.Lpic2
-.Lpic2:	lda	$rem_4bit,rem_4bit-.Lpic2($rem_4bit)
+	bsr	$t0,picmeup
+	nop
 
 .Louter:
 	extql	$inhi,$inp,$inhi
@@ -436,11 +436,20 @@ $code.=<<___;
 .end	gcm_ghash_4bit
 
 .align	4
+.ent	picmeup
+picmeup:
+	.frame	sp,0,$t0
+	.prologue 0
+	br	$rem_4bit,.Lpic
+.Lpic:	lda	$rem_4bit,12($rem_4bit)
+	ret	($t0)
+.end	picmeup
+	nop
 rem_4bit:
-	.quad	0x0000<<48, 0x1C20<<48, 0x3840<<48, 0x2460<<48
-	.quad	0x7080<<48, 0x6CA0<<48, 0x48C0<<48, 0x54E0<<48
-	.quad	0xE100<<48, 0xFD20<<48, 0xD940<<48, 0xC560<<48
-	.quad	0x9180<<48, 0x8DA0<<48, 0xA9C0<<48, 0xB5E0<<48
+	.long	0,0x0000<<16, 0,0x1C20<<16, 0,0x3840<<16, 0,0x2460<<16
+	.long	0,0x7080<<16, 0,0x6CA0<<16, 0,0x48C0<<16, 0,0x54E0<<16
+	.long	0,0xE100<<16, 0,0xFD20<<16, 0,0xD940<<16, 0,0xC560<<16
+	.long	0,0x9180<<16, 0,0x8DA0<<16, 0,0xA9C0<<16, 0,0xB5E0<<16
 .ascii	"GHASH for Alpha, CRYPTOGAMS by <appro\@openssl.org>"
 .align	4
 
diff --git a/src/lib/libcrypto/modes/asm/ghash-parisc.pl b/src/lib/libcrypto/modes/asm/ghash-parisc.pl
index 8c7454ee93..d5ad96b403 100644
--- a/src/lib/libcrypto/modes/asm/ghash-parisc.pl
+++ b/src/lib/libcrypto/modes/asm/ghash-parisc.pl
@@ -724,6 +724,7 @@ foreach (split("\n",$code)) {
 		s/cmpb,\*/comb,/;
 		s/,\*/,/;
 	}
+	s/\bbv\b/bve/	if ($SIZE_T==8);
 	print $_,"\n";
 }
 
diff --git a/src/lib/libcrypto/modes/asm/ghash-x86.pl b/src/lib/libcrypto/modes/asm/ghash-x86.pl
index 6b09669d47..83c727e07f 100644
--- a/src/lib/libcrypto/modes/asm/ghash-x86.pl
+++ b/src/lib/libcrypto/modes/asm/ghash-x86.pl
@@ -635,7 +635,7 @@ sub mmx_loop() {
     { my @lo  = ("mm0","mm1","mm2");
       my @hi  = ("mm3","mm4","mm5");
       my @tmp = ("mm6","mm7");
-      my $off1=0,$off2=0,$i;
+      my ($off1,$off2,$i) = (0,0,);
 
       &add	($Htbl,128);			# optimize for size
       &lea	("edi",&DWP(16+128,"esp"));
@@ -883,7 +883,7 @@ sub reduction_alg9 {	# 17/13 times faster than Intel version
 my ($Xhi,$Xi) = @_;
 
 	# 1st phase
-	&movdqa		($T1,$Xi)		#
+	&movdqa		($T1,$Xi);		#
 	&psllq		($Xi,1);
 	&pxor		($Xi,$T1);		#
 	&psllq		($Xi,5);		#
@@ -1019,7 +1019,7 @@ my ($Xhi,$Xi) = @_;
 	&movdqa		($Xhn,$Xn);
 	 &pxor		($Xhi,$T1);		# "Ii+Xi", consume early
 
-	  &movdqa	($T1,$Xi)		#&reduction_alg9($Xhi,$Xi); 1st phase
+	  &movdqa	($T1,$Xi);		#&reduction_alg9($Xhi,$Xi); 1st phase
 	  &psllq	($Xi,1);
 	  &pxor		($Xi,$T1);		#
 	  &psllq	($Xi,5);		#
diff --git a/src/lib/libcrypto/modes/asm/ghash-x86_64.pl b/src/lib/libcrypto/modes/asm/ghash-x86_64.pl
index a5ae180882..38d779edbc 100644
--- a/src/lib/libcrypto/modes/asm/ghash-x86_64.pl
+++ b/src/lib/libcrypto/modes/asm/ghash-x86_64.pl
@@ -50,7 +50,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 # common register layout
 $nlo="%rax";
diff --git a/src/lib/libcrypto/modes/cbc128.c b/src/lib/libcrypto/modes/cbc128.c
index 3d3782cbe1..0e54f75470 100644
--- a/src/lib/libcrypto/modes/cbc128.c
+++ b/src/lib/libcrypto/modes/cbc128.c
@@ -117,7 +117,7 @@ void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
 			unsigned char ivec[16], block128_f block)
 {
 	size_t n;
-	union { size_t align; unsigned char c[16]; } tmp;
+	union { size_t t[16/sizeof(size_t)]; unsigned char c[16]; } tmp;
 
 	assert(in && out && key && ivec);
 
@@ -137,11 +137,13 @@ void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
 				out += 16;
 			}
 		}
-		else {
+		else  if (16%sizeof(size_t) == 0) { /* always true */
 			while (len>=16) {
+				size_t *out_t=(size_t *)out, *iv_t=(size_t *)iv;
+
 				(*block)(in, out, key);
-				for(n=0; n<16; n+=sizeof(size_t))
-					*(size_t *)(out+n) ^= *(size_t *)(iv+n);
+				for(n=0; n<16/sizeof(size_t); n++)
+					out_t[n] ^= iv_t[n];
 				iv = in;
 				len -= 16;
 				in  += 16;
@@ -165,15 +167,16 @@ void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out,
 				out += 16;
 			}
 		}
-		else {
-			size_t c;
+		else if (16%sizeof(size_t) == 0) { /* always true */
 			while (len>=16) {
+				size_t c, *out_t=(size_t *)out, *ivec_t=(size_t *)ivec;
+				const size_t *in_t=(const size_t *)in;
+
 				(*block)(in, tmp.c, key);
-				for(n=0; n<16; n+=sizeof(size_t)) {
-					c = *(size_t *)(in+n);
-					*(size_t *)(out+n) =
-					*(size_t *)(tmp.c+n) ^ *(size_t *)(ivec+n);
-					*(size_t *)(ivec+n) = c;
+				for(n=0; n<16/sizeof(size_t); n++) {
+					c = in_t[n];
+					out_t[n] = tmp.t[n] ^ ivec_t[n];
+					ivec_t[n] = c;
 				}
 				len -= 16;
 				in  += 16;
diff --git a/src/lib/libcrypto/modes/ccm128.c b/src/lib/libcrypto/modes/ccm128.c
index c9b35e5b35..3ce11d0d98 100644
--- a/src/lib/libcrypto/modes/ccm128.c
+++ b/src/lib/libcrypto/modes/ccm128.c
@@ -87,7 +87,7 @@ int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx,
 		ctx->nonce.c[11] = (u8)(mlen>>(32%(sizeof(mlen)*8)));
 	}
 	else
-		*(u32*)(&ctx->nonce.c[8]) = 0;
+		ctx->nonce.u[1] = 0;
 
 	ctx->nonce.c[12] = (u8)(mlen>>24);
 	ctx->nonce.c[13] = (u8)(mlen>>16);
diff --git a/src/lib/libcrypto/modes/cts128.c b/src/lib/libcrypto/modes/cts128.c
index c0e1f3696c..2d583de6f6 100644
--- a/src/lib/libcrypto/modes/cts128.c
+++ b/src/lib/libcrypto/modes/cts128.c
@@ -108,12 +108,8 @@ size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out,
 	(*cbc)(in,out-16,residue,key,ivec,1);
 	memcpy(out,tmp.c,residue);
 #else
-	{
-	size_t n;
-	for (n=0; n<16; n+=sizeof(size_t))
-		*(size_t *)(tmp.c+n) = 0;
+	memset(tmp.c,0,sizeof(tmp));
 	memcpy(tmp.c,in,residue);
-	}
 	memcpy(out,out-16,residue);
 	(*cbc)(tmp.c,out-16,16,key,ivec,1);
 #endif
@@ -144,12 +140,8 @@ size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out,
 #if defined(CBC_HANDLES_TRUNCATED_IO)
 	(*cbc)(in,out-16+residue,residue,key,ivec,1);
 #else
-	{
-	size_t n;
-	for (n=0; n<16; n+=sizeof(size_t))
-		*(size_t *)(tmp.c+n) = 0;
+	memset(tmp.c,0,sizeof(tmp));
 	memcpy(tmp.c,in,residue);
-	}
 	(*cbc)(tmp.c,out-16+residue,16,key,ivec,1);
 #endif
 	return len+residue;
@@ -177,8 +169,7 @@ size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, unsigned char *out,
 
 	(*block)(in,tmp.c+16,key);
 
-	for (n=0; n<16; n+=sizeof(size_t))
-		*(size_t *)(tmp.c+n) = *(size_t *)(tmp.c+16+n);
+	memcpy(tmp.c,tmp.c+16,16);
 	memcpy(tmp.c,in+16,residue);
 	(*block)(tmp.c,tmp.c,key);
 
@@ -220,8 +211,7 @@ size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, unsigned char *o
 
 	(*block)(in+residue,tmp.c+16,key);
 
-	for (n=0; n<16; n+=sizeof(size_t))
-		*(size_t *)(tmp.c+n) = *(size_t *)(tmp.c+16+n);
+	memcpy(tmp.c,tmp.c+16,16);
 	memcpy(tmp.c,in,residue);
 	(*block)(tmp.c,tmp.c,key);
 
@@ -240,7 +230,7 @@ size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, unsigned char *o
 size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
 			size_t len, const void *key,
 			unsigned char ivec[16], cbc128_f cbc)
-{	size_t residue, n;
+{	size_t residue;
 	union { size_t align; unsigned char c[32]; } tmp;
 
 	assert (in && out && key && ivec);
@@ -257,8 +247,7 @@ size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
 		out += len;
 	}
 
-	for (n=16; n<32; n+=sizeof(size_t))
-		*(size_t *)(tmp.c+n) = 0;
+	memset(tmp.c,0,sizeof(tmp));
 	/* this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0] */
 	(*cbc)(in,tmp.c,16,key,tmp.c+16,0);
 
@@ -275,7 +264,7 @@ size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out,
 size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out,
 			size_t len, const void *key,
 			unsigned char ivec[16], cbc128_f cbc)
-{	size_t residue, n;
+{	size_t residue;
 	union { size_t align; unsigned char c[32]; } tmp;
 
 	assert (in && out && key && ivec);
@@ -297,8 +286,7 @@ size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out,
 		out += len;
 	}
 
-	for (n=16; n<32; n+=sizeof(size_t))
-		*(size_t *)(tmp.c+n) = 0;
+	memset(tmp.c,0,sizeof(tmp));
 	/* this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0] */
 	(*cbc)(in+residue,tmp.c,16,key,tmp.c+16,0);
 
diff --git a/src/lib/libcrypto/modes/gcm128.c b/src/lib/libcrypto/modes/gcm128.c
index 7d6d034970..e1dc2b0f47 100644
--- a/src/lib/libcrypto/modes/gcm128.c
+++ b/src/lib/libcrypto/modes/gcm128.c
@@ -723,7 +723,7 @@ void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx,void *key,block128_f block)
 #  endif
 	gcm_init_4bit(ctx->Htable,ctx->H.u);
 #  if	defined(GHASH_ASM_X86)			/* x86 only */
-#   if defined(OPENSSL_IA32_SSE2)
+#   if	defined(OPENSSL_IA32_SSE2)
 	if (OPENSSL_ia32cap_P[0]&(1<<25)) {	/* check SSE bit */
 #   else
 	if (OPENSSL_ia32cap_P[0]&(1<<23)) {	/* check MMX bit */
@@ -810,7 +810,11 @@ void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx,const unsigned char *iv,size_t len)
 		GCM_MUL(ctx,Yi);
 
 		if (is_endian.little)
+#ifdef BSWAP4
+			ctr = BSWAP4(ctx->Yi.d[3]);
+#else
 			ctr = GETU32(ctx->Yi.c+12);
+#endif
 		else
 			ctr = ctx->Yi.d[3];
 	}
@@ -818,7 +822,11 @@ void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx,const unsigned char *iv,size_t len)
 	(*ctx->block)(ctx->Yi.c,ctx->EK0.c,ctx->key);
 	++ctr;
 	if (is_endian.little)
+#ifdef BSWAP4
+		ctx->Yi.d[3] = BSWAP4(ctr);
+#else
 		PUTU32(ctx->Yi.c+12,ctr);
+#endif
 	else
 		ctx->Yi.d[3] = ctr;
 }
@@ -913,7 +921,11 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
 	}
 
 	if (is_endian.little)
+#ifdef BSWAP4
+		ctr = BSWAP4(ctx->Yi.d[3]);
+#else
 		ctr = GETU32(ctx->Yi.c+12);
+#endif
 	else
 		ctr = ctx->Yi.d[3];
 
@@ -941,15 +953,21 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
 		    size_t j=GHASH_CHUNK;
 
 		    while (j) {
+		    	size_t *out_t=(size_t *)out;
+		    	const size_t *in_t=(const size_t *)in;
+
 			(*block)(ctx->Yi.c,ctx->EKi.c,key);
 			++ctr;
 			if (is_endian.little)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
 				PUTU32(ctx->Yi.c+12,ctr);
+#endif
 			else
 				ctx->Yi.d[3] = ctr;
-			for (i=0; i<16; i+=sizeof(size_t))
-				*(size_t *)(out+i) =
-				*(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
+			for (i=0; i<16/sizeof(size_t); ++i)
+				out_t[i] = in_t[i] ^ ctx->EKi.t[i];
 			out += 16;
 			in  += 16;
 			j   -= 16;
@@ -961,15 +979,21 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
 		    size_t j=i;
 
 		    while (len>=16) {
+		    	size_t *out_t=(size_t *)out;
+		    	const size_t *in_t=(const size_t *)in;
+
 			(*block)(ctx->Yi.c,ctx->EKi.c,key);
 			++ctr;
 			if (is_endian.little)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
 				PUTU32(ctx->Yi.c+12,ctr);
+#endif
 			else
 				ctx->Yi.d[3] = ctr;
-			for (i=0; i<16; i+=sizeof(size_t))
-				*(size_t *)(out+i) =
-				*(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
+			for (i=0; i<16/sizeof(size_t); ++i)
+				out_t[i] = in_t[i] ^ ctx->EKi.t[i];
 			out += 16;
 			in  += 16;
 			len -= 16;
@@ -978,16 +1002,22 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
 		}
 #else
 		while (len>=16) {
+		    	size_t *out_t=(size_t *)out;
+		    	const size_t *in_t=(const size_t *)in;
+
 			(*block)(ctx->Yi.c,ctx->EKi.c,key);
 			++ctr;
 			if (is_endian.little)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
 				PUTU32(ctx->Yi.c+12,ctr);
+#endif
 			else
 				ctx->Yi.d[3] = ctr;
-			for (i=0; i<16; i+=sizeof(size_t))
-				*(size_t *)(ctx->Xi.c+i) ^=
-				*(size_t *)(out+i) =
-				*(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
+			for (i=0; i<16/sizeof(size_t); ++i)
+				ctx->Xi.t[i] ^=
+				out_t[i] = in_t[i]^ctx->EKi.t[i];
 			GCM_MUL(ctx,Xi);
 			out += 16;
 			in  += 16;
@@ -998,7 +1028,11 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
 			(*block)(ctx->Yi.c,ctx->EKi.c,key);
 			++ctr;
 			if (is_endian.little)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
 				PUTU32(ctx->Yi.c+12,ctr);
+#endif
 			else
 				ctx->Yi.d[3] = ctr;
 			while (len--) {
@@ -1016,7 +1050,11 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx,
 			(*block)(ctx->Yi.c,ctx->EKi.c,key);
 			++ctr;
 			if (is_endian.little)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
 				PUTU32(ctx->Yi.c+12,ctr);
+#endif
 			else
 				ctx->Yi.d[3] = ctr;
 		}
@@ -1060,7 +1098,11 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
 	}
 
 	if (is_endian.little)
+#ifdef BSWAP4
+		ctr = BSWAP4(ctx->Yi.d[3]);
+#else
 		ctr = GETU32(ctx->Yi.c+12);
+#endif
 	else
 		ctr = ctx->Yi.d[3];
 
@@ -1091,15 +1133,21 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
 
 		    GHASH(ctx,in,GHASH_CHUNK);
 		    while (j) {
+		    	size_t *out_t=(size_t *)out;
+		    	const size_t *in_t=(const size_t *)in;
+
 			(*block)(ctx->Yi.c,ctx->EKi.c,key);
 			++ctr;
 			if (is_endian.little)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
 				PUTU32(ctx->Yi.c+12,ctr);
+#endif
 			else
 				ctx->Yi.d[3] = ctr;
-			for (i=0; i<16; i+=sizeof(size_t))
-				*(size_t *)(out+i) =
-				*(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
+			for (i=0; i<16/sizeof(size_t); ++i)
+				out_t[i] = in_t[i]^ctx->EKi.t[i];
 			out += 16;
 			in  += 16;
 			j   -= 16;
@@ -1109,15 +1157,21 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
 		if ((i = (len&(size_t)-16))) {
 		    GHASH(ctx,in,i);
 		    while (len>=16) {
+		    	size_t *out_t=(size_t *)out;
+		    	const size_t *in_t=(const size_t *)in;
+
 			(*block)(ctx->Yi.c,ctx->EKi.c,key);
 			++ctr;
 			if (is_endian.little)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
 				PUTU32(ctx->Yi.c+12,ctr);
+#endif
 			else
 				ctx->Yi.d[3] = ctr;
-			for (i=0; i<16; i+=sizeof(size_t))
-				*(size_t *)(out+i) =
-				*(size_t *)(in+i)^*(size_t *)(ctx->EKi.c+i);
+			for (i=0; i<16/sizeof(size_t); ++i)
+				out_t[i] = in_t[i]^ctx->EKi.t[i];
 			out += 16;
 			in  += 16;
 			len -= 16;
@@ -1125,16 +1179,23 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
 		}
 #else
 		while (len>=16) {
+		    	size_t *out_t=(size_t *)out;
+		    	const size_t *in_t=(const size_t *)in;
+
 			(*block)(ctx->Yi.c,ctx->EKi.c,key);
 			++ctr;
 			if (is_endian.little)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
 				PUTU32(ctx->Yi.c+12,ctr);
+#endif
 			else
 				ctx->Yi.d[3] = ctr;
-			for (i=0; i<16; i+=sizeof(size_t)) {
-				size_t c = *(size_t *)(in+i);
-				*(size_t *)(out+i) = c^*(size_t *)(ctx->EKi.c+i);
-				*(size_t *)(ctx->Xi.c+i) ^= c;
+			for (i=0; i<16/sizeof(size_t); ++i) {
+				size_t c = in[i];
+				out[i] = c^ctx->EKi.t[i];
+				ctx->Xi.t[i] ^= c;
 			}
 			GCM_MUL(ctx,Xi);
 			out += 16;
@@ -1146,7 +1207,11 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
 			(*block)(ctx->Yi.c,ctx->EKi.c,key);
 			++ctr;
 			if (is_endian.little)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
 				PUTU32(ctx->Yi.c+12,ctr);
+#endif
 			else
 				ctx->Yi.d[3] = ctr;
 			while (len--) {
@@ -1167,7 +1232,11 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx,
 			(*block)(ctx->Yi.c,ctx->EKi.c,key);
 			++ctr;
 			if (is_endian.little)
+#ifdef BSWAP4
+				ctx->Yi.d[3] = BSWAP4(ctr);
+#else
 				PUTU32(ctx->Yi.c+12,ctr);
+#endif
 			else
 				ctx->Yi.d[3] = ctr;
 		}
@@ -1212,7 +1281,11 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
 	}
 
 	if (is_endian.little)
+#ifdef BSWAP4
+		ctr = BSWAP4(ctx->Yi.d[3]);
+#else
 		ctr = GETU32(ctx->Yi.c+12);
+#endif
 	else
 		ctr = ctx->Yi.d[3];
 
@@ -1234,7 +1307,11 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
 		(*stream)(in,out,GHASH_CHUNK/16,key,ctx->Yi.c);
 		ctr += GHASH_CHUNK/16;
 		if (is_endian.little)
+#ifdef BSWAP4
+			ctx->Yi.d[3] = BSWAP4(ctr);
+#else
 			PUTU32(ctx->Yi.c+12,ctr);
+#endif
 		else
 			ctx->Yi.d[3] = ctr;
 		GHASH(ctx,out,GHASH_CHUNK);
@@ -1249,7 +1326,11 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
 		(*stream)(in,out,j,key,ctx->Yi.c);
 		ctr += (unsigned int)j;
 		if (is_endian.little)
+#ifdef BSWAP4
+			ctx->Yi.d[3] = BSWAP4(ctr);
+#else
 			PUTU32(ctx->Yi.c+12,ctr);
+#endif
 		else
 			ctx->Yi.d[3] = ctr;
 		in  += i;
@@ -1269,7 +1350,11 @@ int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx,
 		(*ctx->block)(ctx->Yi.c,ctx->EKi.c,key);
 		++ctr;
 		if (is_endian.little)
+#ifdef BSWAP4
+			ctx->Yi.d[3] = BSWAP4(ctr);
+#else
 			PUTU32(ctx->Yi.c+12,ctr);
+#endif
 		else
 			ctx->Yi.d[3] = ctr;
 		while (len--) {
@@ -1311,7 +1396,11 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
 	}
 
 	if (is_endian.little)
+#ifdef BSWAP4
+		ctr = BSWAP4(ctx->Yi.d[3]);
+#else
 		ctr = GETU32(ctx->Yi.c+12);
+#endif
 	else
 		ctr = ctx->Yi.d[3];
 
@@ -1336,7 +1425,11 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
 		(*stream)(in,out,GHASH_CHUNK/16,key,ctx->Yi.c);
 		ctr += GHASH_CHUNK/16;
 		if (is_endian.little)
+#ifdef BSWAP4
+			ctx->Yi.d[3] = BSWAP4(ctr);
+#else
 			PUTU32(ctx->Yi.c+12,ctr);
+#endif
 		else
 			ctx->Yi.d[3] = ctr;
 		out += GHASH_CHUNK;
@@ -1362,7 +1455,11 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
 		(*stream)(in,out,j,key,ctx->Yi.c);
 		ctr += (unsigned int)j;
 		if (is_endian.little)
+#ifdef BSWAP4
+			ctx->Yi.d[3] = BSWAP4(ctr);
+#else
 			PUTU32(ctx->Yi.c+12,ctr);
+#endif
 		else
 			ctx->Yi.d[3] = ctr;
 		out += i;
@@ -1373,7 +1470,11 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx,
 		(*ctx->block)(ctx->Yi.c,ctx->EKi.c,key);
 		++ctr;
 		if (is_endian.little)
+#ifdef BSWAP4
+			ctx->Yi.d[3] = BSWAP4(ctr);
+#else
 			PUTU32(ctx->Yi.c+12,ctr);
+#endif
 		else
 			ctx->Yi.d[3] = ctr;
 		while (len--) {
@@ -1398,7 +1499,7 @@ int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx,const unsigned char *tag,
 	void (*gcm_gmult_p)(u64 Xi[2],const u128 Htable[16])	= ctx->gmult;
 #endif
 
-	if (ctx->mres)
+	if (ctx->mres || ctx->ares)
 		GCM_MUL(ctx,Xi);
 
 	if (is_endian.little) {
@@ -1669,6 +1770,46 @@ static const u8	IV18[]={0x93,0x13,0x22,0x5d,0xf8,0x84,0x06,0xe5,0x55,0x90,0x9c,0
 			0xa2,0x41,0x89,0x97,0x20,0x0e,0xf8,0x2e,0x44,0xae,0x7e,0x3f},
 		T18[]= {0xa4,0x4a,0x82,0x66,0xee,0x1c,0x8e,0xb0,0xc8,0xb5,0xd4,0xcf,0x5a,0xe9,0xf1,0x9a};
 
+/* Test Case 19 */
+#define K19 K1
+#define P19 P1
+#define IV19 IV1
+#define C19 C1
+static const u8 A19[]= {0xd9,0x31,0x32,0x25,0xf8,0x84,0x06,0xe5,0xa5,0x59,0x09,0xc5,0xaf,0xf5,0x26,0x9a,
+			0x86,0xa7,0xa9,0x53,0x15,0x34,0xf7,0xda,0x2e,0x4c,0x30,0x3d,0x8a,0x31,0x8a,0x72,
+			0x1c,0x3c,0x0c,0x95,0x95,0x68,0x09,0x53,0x2f,0xcf,0x0e,0x24,0x49,0xa6,0xb5,0x25,
+			0xb1,0x6a,0xed,0xf5,0xaa,0x0d,0xe6,0x57,0xba,0x63,0x7b,0x39,0x1a,0xaf,0xd2,0x55,
+			0x52,0x2d,0xc1,0xf0,0x99,0x56,0x7d,0x07,0xf4,0x7f,0x37,0xa3,0x2a,0x84,0x42,0x7d,
+			0x64,0x3a,0x8c,0xdc,0xbf,0xe5,0xc0,0xc9,0x75,0x98,0xa2,0xbd,0x25,0x55,0xd1,0xaa,
+			0x8c,0xb0,0x8e,0x48,0x59,0x0d,0xbb,0x3d,0xa7,0xb0,0x8b,0x10,0x56,0x82,0x88,0x38,
+			0xc5,0xf6,0x1e,0x63,0x93,0xba,0x7a,0x0a,0xbc,0xc9,0xf6,0x62,0x89,0x80,0x15,0xad},
+		T19[]= {0x5f,0xea,0x79,0x3a,0x2d,0x6f,0x97,0x4d,0x37,0xe6,0x8e,0x0c,0xb8,0xff,0x94,0x92};
+
+/* Test Case 20 */
+#define K20 K1
+#define A20 A1
+static const u8 IV20[64]={0xff,0xff,0xff,0xff},	/* this results in 0xff in counter LSB */
+		P20[288],
+		C20[]= {0x56,0xb3,0x37,0x3c,0xa9,0xef,0x6e,0x4a,0x2b,0x64,0xfe,0x1e,0x9a,0x17,0xb6,0x14,
+			0x25,0xf1,0x0d,0x47,0xa7,0x5a,0x5f,0xce,0x13,0xef,0xc6,0xbc,0x78,0x4a,0xf2,0x4f,
+			0x41,0x41,0xbd,0xd4,0x8c,0xf7,0xc7,0x70,0x88,0x7a,0xfd,0x57,0x3c,0xca,0x54,0x18,
+			0xa9,0xae,0xff,0xcd,0x7c,0x5c,0xed,0xdf,0xc6,0xa7,0x83,0x97,0xb9,0xa8,0x5b,0x49,
+			0x9d,0xa5,0x58,0x25,0x72,0x67,0xca,0xab,0x2a,0xd0,0xb2,0x3c,0xa4,0x76,0xa5,0x3c,
+			0xb1,0x7f,0xb4,0x1c,0x4b,0x8b,0x47,0x5c,0xb4,0xf3,0xf7,0x16,0x50,0x94,0xc2,0x29,
+			0xc9,0xe8,0xc4,0xdc,0x0a,0x2a,0x5f,0xf1,0x90,0x3e,0x50,0x15,0x11,0x22,0x13,0x76,
+			0xa1,0xcd,0xb8,0x36,0x4c,0x50,0x61,0xa2,0x0c,0xae,0x74,0xbc,0x4a,0xcd,0x76,0xce,
+			0xb0,0xab,0xc9,0xfd,0x32,0x17,0xef,0x9f,0x8c,0x90,0xbe,0x40,0x2d,0xdf,0x6d,0x86,
+			0x97,0xf4,0xf8,0x80,0xdf,0xf1,0x5b,0xfb,0x7a,0x6b,0x28,0x24,0x1e,0xc8,0xfe,0x18,
+			0x3c,0x2d,0x59,0xe3,0xf9,0xdf,0xff,0x65,0x3c,0x71,0x26,0xf0,0xac,0xb9,0xe6,0x42,
+			0x11,0xf4,0x2b,0xae,0x12,0xaf,0x46,0x2b,0x10,0x70,0xbe,0xf1,0xab,0x5e,0x36,0x06,
+			0x87,0x2c,0xa1,0x0d,0xee,0x15,0xb3,0x24,0x9b,0x1a,0x1b,0x95,0x8f,0x23,0x13,0x4c,
+			0x4b,0xcc,0xb7,0xd0,0x32,0x00,0xbc,0xe4,0x20,0xa2,0xf8,0xeb,0x66,0xdc,0xf3,0x64,
+			0x4d,0x14,0x23,0xc1,0xb5,0x69,0x90,0x03,0xc1,0x3e,0xce,0xf4,0xbf,0x38,0xa3,0xb6,
+			0x0e,0xed,0xc3,0x40,0x33,0xba,0xc1,0x90,0x27,0x83,0xdc,0x6d,0x89,0xe2,0xe7,0x74,
+			0x18,0x8a,0x43,0x9c,0x7e,0xbc,0xc0,0x67,0x2d,0xbd,0xa4,0xdd,0xcf,0xb2,0x79,0x46,
+			0x13,0xb0,0xbe,0x41,0x31,0x5e,0xf7,0x78,0x70,0x8a,0x70,0xee,0x7d,0x75,0x16,0x5c},
+		T20[]= {0x8b,0x30,0x7f,0x6b,0x33,0x28,0x6d,0x0a,0xb0,0x26,0xa9,0xed,0x3f,0xe1,0xe8,0x5f};
+
 #define TEST_CASE(n)	do {					\
 	u8 out[sizeof(P##n)];					\
 	AES_set_encrypt_key(K##n,sizeof(K##n)*8,&key);		\
@@ -1713,6 +1854,8 @@ int main()
 	TEST_CASE(16);
 	TEST_CASE(17);
 	TEST_CASE(18);
+	TEST_CASE(19);
+	TEST_CASE(20);
 
 #ifdef OPENSSL_CPUID_OBJ
 	{
@@ -1743,11 +1886,16 @@ int main()
 			ctr_t/(double)sizeof(buf),
 			(gcm_t-ctr_t)/(double)sizeof(buf));
 #ifdef GHASH
-	GHASH(&ctx,buf.c,sizeof(buf));
+	{
+	void (*gcm_ghash_p)(u64 Xi[2],const u128 Htable[16],
+				const u8 *inp,size_t len)	= ctx.ghash;
+
+	GHASH((&ctx),buf.c,sizeof(buf));
 	start = OPENSSL_rdtsc();
-	for (i=0;i<100;++i) GHASH(&ctx,buf.c,sizeof(buf));
+	for (i=0;i<100;++i) GHASH((&ctx),buf.c,sizeof(buf));
 	gcm_t = OPENSSL_rdtsc() - start;
 	printf("%.2f\n",gcm_t/(double)sizeof(buf)/(double)i);
+	}
 #endif
 	}
 #endif
diff --git a/src/lib/libcrypto/modes/modes_lcl.h b/src/lib/libcrypto/modes/modes_lcl.h
index b6dc3c336f..9d83e12844 100644
--- a/src/lib/libcrypto/modes/modes_lcl.h
+++ b/src/lib/libcrypto/modes/modes_lcl.h
@@ -29,10 +29,7 @@ typedef unsigned char u8;
 #if defined(__i386)	|| defined(__i386__)	|| \
     defined(__x86_64)	|| defined(__x86_64__)	|| \
     defined(_M_IX86)	|| defined(_M_AMD64)	|| defined(_M_X64) || \
-    defined(__s390__)	|| defined(__s390x__)	|| \
-    ( (defined(__arm__)	|| defined(__arm)) && \
-      (defined(__ARM_ARCH_7__)	|| defined(__ARM_ARCH_7A__) || \
-       defined(__ARM_ARCH_7R__)	|| defined(__ARM_ARCH_7M__)) )
+    defined(__s390__)	|| defined(__s390x__)
 # undef STRICT_ALIGNMENT
 #endif
 
@@ -101,8 +98,8 @@ typedef struct { u64 hi,lo; } u128;
 
 struct gcm128_context {
 	/* Following 6 names follow names in GCM specification */
-	union { u64 u[2]; u32 d[4]; u8 c[16]; }	Yi,EKi,EK0,len,
-						Xi,H;
+	union { u64 u[2]; u32 d[4]; u8 c[16]; size_t t[16/sizeof(size_t)]; }
+	  Yi,EKi,EK0,len,Xi,H;
 	/* Relative position of Xi, H and pre-computed Htable is used
 	 * in some assembler modules, i.e. don't change the order! */
 #if TABLE_BITS==8
diff --git a/src/lib/libcrypto/objects/o_names.c b/src/lib/libcrypto/objects/o_names.c
index 84380a96a9..4a548c2ed4 100644
--- a/src/lib/libcrypto/objects/o_names.c
+++ b/src/lib/libcrypto/objects/o_names.c
@@ -73,7 +73,7 @@ int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *),
 		name_funcs_stack=sk_NAME_FUNCS_new_null();
 		MemCheck_on();
 		}
-	if ((name_funcs_stack == NULL))
+	if (name_funcs_stack == NULL)
 		{
 		/* ERROR */
 		return(0);
diff --git a/src/lib/libcrypto/ocsp/ocsp_vfy.c b/src/lib/libcrypto/ocsp/ocsp_vfy.c
index 415d67e61c..276718304d 100644
--- a/src/lib/libcrypto/ocsp/ocsp_vfy.c
+++ b/src/lib/libcrypto/ocsp/ocsp_vfy.c
@@ -91,9 +91,12 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
 		{
 		EVP_PKEY *skey;
 		skey = X509_get_pubkey(signer);
-		ret = OCSP_BASICRESP_verify(bs, skey, 0);
-		EVP_PKEY_free(skey);
-		if(ret <= 0)
+		if (skey)
+			{
+			ret = OCSP_BASICRESP_verify(bs, skey, 0);
+			EVP_PKEY_free(skey);
+			}
+		if(!skey || ret <= 0)
 			{
 			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE);
 			goto end;
@@ -108,6 +111,7 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
 			init_res = X509_STORE_CTX_init(&ctx, st, signer, bs->certs);
 		if(!init_res)
 			{
+			ret = -1;
 			OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,ERR_R_X509_LIB);
 			goto end;
 			}
diff --git a/src/lib/libcrypto/opensslv.h b/src/lib/libcrypto/opensslv.h
index 71be3590af..ebe7180723 100644
--- a/src/lib/libcrypto/opensslv.h
+++ b/src/lib/libcrypto/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	0x1000103fL
+#define OPENSSL_VERSION_NUMBER	0x1000107fL
 #ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1c-fips 10 May 2012"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1g-fips 7 Apr 2014"
 #else
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1c 10 May 2012"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1g 7 Apr 2014"
 #endif
 #define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
 
diff --git a/src/lib/libcrypto/pariscid.pl b/src/lib/libcrypto/pariscid.pl
index 477ec9b87d..bfc56fdc7f 100644
--- a/src/lib/libcrypto/pariscid.pl
+++ b/src/lib/libcrypto/pariscid.pl
@@ -97,33 +97,33 @@ OPENSSL_cleanse
 	.PROC
 	.CALLINFO	NO_CALLS
 	.ENTRY
-	cmpib,*=	0,$len,Ldone
+	cmpib,*=	0,$len,L\$done
 	nop
-	cmpib,*>>=	15,$len,Little
+	cmpib,*>>=	15,$len,L\$ittle
 	ldi		$SIZE_T-1,%r1
 
-Lalign
+L\$align
 	and,*<>		$inp,%r1,%r28
-	b,n		Laligned
+	b,n		L\$aligned
 	stb		%r0,0($inp)
 	ldo		-1($len),$len
-	b		Lalign
+	b		L\$align
 	ldo		1($inp),$inp
 
-Laligned
+L\$aligned
 	andcm		$len,%r1,%r28
-Lot
+L\$ot
 	$ST		%r0,0($inp)
-	addib,*<>	-$SIZE_T,%r28,Lot
+	addib,*<>	-$SIZE_T,%r28,L\$ot
 	ldo		$SIZE_T($inp),$inp
 
 	and,*<>		$len,%r1,$len
-	b,n		Ldone
-Little
+	b,n		L\$done
+L\$ittle
 	stb		%r0,0($inp)
-	addib,*<>	-1,$len,Little
+	addib,*<>	-1,$len,L\$ittle
 	ldo		1($inp),$inp
-Ldone
+L\$done
 	bv		($rp)
 	.EXIT
 	nop
@@ -151,7 +151,7 @@ OPENSSL_instrument_bus
 	ldw		0($out),$tick
 	add		$diff,$tick,$tick
 	stw		$tick,0($out)
-Loop
+L\$oop
 	mfctl		%cr16,$tick
 	sub		$tick,$lasttick,$diff
 	copy		$tick,$lasttick
@@ -161,7 +161,7 @@ Loop
 	add		$diff,$tick,$tick
 	stw		$tick,0($out)
 
-	addib,<>	-1,$cnt,Loop
+	addib,<>	-1,$cnt,L\$oop
 	addi		4,$out,$out
 
 	bv		($rp)
@@ -190,14 +190,14 @@ OPENSSL_instrument_bus2
 	mfctl		%cr16,$tick
 	sub		$tick,$lasttick,$diff
 	copy		$tick,$lasttick
-Loop2
+L\$oop2
 	copy		$diff,$lastdiff
 	fdc		0($out)
 	ldw		0($out),$tick
 	add		$diff,$tick,$tick
 	stw		$tick,0($out)
 
-	addib,=		-1,$max,Ldone2
+	addib,=		-1,$max,L\$done2
 	nop
 
 	mfctl		%cr16,$tick
@@ -208,17 +208,18 @@ Loop2
 
 	ldi		1,%r1
 	xor		%r1,$tick,$tick
-	addb,<>		$tick,$cnt,Loop2
+	addb,<>		$tick,$cnt,L\$oop2
 	shladd,l	$tick,2,$out,$out
-Ldone2
+L\$done2
 	bv		($rp)
 	.EXIT
 	add		$rv,$cnt,$rv
 	.PROCEND
 ___
 }
-$code =~ s/cmpib,\*/comib,/gm if ($SIZE_T==4);
-$code =~ s/,\*/,/gm if ($SIZE_T==4);
+$code =~ s/cmpib,\*/comib,/gm	if ($SIZE_T==4);
+$code =~ s/,\*/,/gm		if ($SIZE_T==4);
+$code =~ s/\bbv\b/bve/gm	if ($SIZE_T==8);
 print $code;
 close STDOUT;
 
diff --git a/src/lib/libcrypto/pem/pem_all.c b/src/lib/libcrypto/pem/pem_all.c
index 3e7a6093ad..eac0460e3e 100644
--- a/src/lib/libcrypto/pem/pem_all.c
+++ b/src/lib/libcrypto/pem/pem_all.c
@@ -193,7 +193,61 @@ RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb,
 
 #endif
 
+#ifdef OPENSSL_FIPS
+
+int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+	if (FIPS_mode())
+		{
+		EVP_PKEY *k;
+		int ret;
+		k = EVP_PKEY_new();
+		if (!k)
+			return 0;
+		EVP_PKEY_set1_RSA(k, x);
+
+		ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
+		EVP_PKEY_free(k);
+		return ret;
+		}
+	else
+		return PEM_ASN1_write_bio((i2d_of_void *)i2d_RSAPrivateKey,
+					PEM_STRING_RSA,bp,x,enc,kstr,klen,cb,u);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+	if (FIPS_mode())
+		{
+		EVP_PKEY *k;
+		int ret;
+		k = EVP_PKEY_new();
+		if (!k)
+			return 0;
+
+		EVP_PKEY_set1_RSA(k, x);
+
+		ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
+		EVP_PKEY_free(k);
+		return ret;
+		}
+	else
+		return PEM_ASN1_write((i2d_of_void *)i2d_RSAPrivateKey,
+					PEM_STRING_RSA,fp,x,enc,kstr,klen,cb,u);
+}
+#endif
+
+#else
+
 IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey)
+
+#endif
+
 IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey)
 IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY)
 
@@ -223,7 +277,59 @@ DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb,
 	return pkey_get_dsa(pktmp, dsa);	/* will free pktmp */
 }
 
+#ifdef OPENSSL_FIPS
+
+int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+	if (FIPS_mode())
+		{
+		EVP_PKEY *k;
+		int ret;
+		k = EVP_PKEY_new();
+		if (!k)
+			return 0;
+		EVP_PKEY_set1_DSA(k, x);
+
+		ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
+		EVP_PKEY_free(k);
+		return ret;
+		}
+	else
+		return PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAPrivateKey,
+					PEM_STRING_DSA,bp,x,enc,kstr,klen,cb,u);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+	if (FIPS_mode())
+		{
+		EVP_PKEY *k;
+		int ret;
+		k = EVP_PKEY_new();
+		if (!k)
+			return 0;
+		EVP_PKEY_set1_DSA(k, x);
+		ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
+		EVP_PKEY_free(k);
+		return ret;
+		}
+	else
+		return PEM_ASN1_write((i2d_of_void *)i2d_DSAPrivateKey,
+					PEM_STRING_DSA,fp,x,enc,kstr,klen,cb,u);
+}
+#endif
+
+#else
+
 IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey)
+
+#endif
+
 IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
 
 #ifndef OPENSSL_NO_FP_API
@@ -269,8 +375,63 @@ EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb,
 
 IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, ECPKParameters)
 
+
+
+#ifdef OPENSSL_FIPS
+
+int PEM_write_bio_ECPrivateKey(BIO *bp, EC_KEY *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+	if (FIPS_mode())
+		{
+		EVP_PKEY *k;
+		int ret;
+		k = EVP_PKEY_new();
+		if (!k)
+			return 0;
+		EVP_PKEY_set1_EC_KEY(k, x);
+
+		ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
+		EVP_PKEY_free(k);
+		return ret;
+		}
+	else
+		return PEM_ASN1_write_bio((i2d_of_void *)i2d_ECPrivateKey,
+						PEM_STRING_ECPRIVATEKEY,
+						bp,x,enc,kstr,klen,cb,u);
+}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_write_ECPrivateKey(FILE *fp, EC_KEY *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+	if (FIPS_mode())
+		{
+		EVP_PKEY *k;
+		int ret;
+		k = EVP_PKEY_new();
+		if (!k)
+			return 0;
+		EVP_PKEY_set1_EC_KEY(k, x);
+		ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
+		EVP_PKEY_free(k);
+		return ret;
+		}
+	else
+		return PEM_ASN1_write((i2d_of_void *)i2d_ECPrivateKey,
+						PEM_STRING_ECPRIVATEKEY,
+						fp,x,enc,kstr,klen,cb,u);
+}
+#endif
+
+#else
+
 IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, ECPrivateKey)
 
+#endif
+
 IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
 
 #ifndef OPENSSL_NO_FP_API
diff --git a/src/lib/libcrypto/pem/pem_info.c b/src/lib/libcrypto/pem/pem_info.c
index 1b2be527ed..cc7f24a9c1 100644
--- a/src/lib/libcrypto/pem/pem_info.c
+++ b/src/lib/libcrypto/pem/pem_info.c
@@ -167,6 +167,7 @@ start:
 #ifndef OPENSSL_NO_RSA
 			if (strcmp(name,PEM_STRING_RSA) == 0)
 			{
+			d2i=(D2I_OF(void))d2i_RSAPrivateKey;
 			if (xi->x_pkey != NULL) 
 				{
 				if (!sk_X509_INFO_push(ret,xi)) goto err;
diff --git a/src/lib/libcrypto/pem/pem_lib.c b/src/lib/libcrypto/pem/pem_lib.c
index cfc89a9921..5a421fc4b6 100644
--- a/src/lib/libcrypto/pem/pem_lib.c
+++ b/src/lib/libcrypto/pem/pem_lib.c
@@ -394,7 +394,8 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
 			goto err;
 		/* The 'iv' is used as the iv and as a salt.  It is
 		 * NOT taken from the BytesToKey function */
-		EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL);
+		if (!EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL))
+			goto err;
 
 		if (kstr == (unsigned char *)buf) OPENSSL_cleanse(buf,PEM_BUFSIZE);
 
@@ -406,12 +407,15 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
 		/* k=strlen(buf); */
 
 		EVP_CIPHER_CTX_init(&ctx);
-		EVP_EncryptInit_ex(&ctx,enc,NULL,key,iv);
-		EVP_EncryptUpdate(&ctx,data,&j,data,i);
-		EVP_EncryptFinal_ex(&ctx,&(data[j]),&i);
+		ret = 1;
+		if (!EVP_EncryptInit_ex(&ctx,enc,NULL,key,iv)
+			|| !EVP_EncryptUpdate(&ctx,data,&j,data,i)
+			|| !EVP_EncryptFinal_ex(&ctx,&(data[j]),&i))
+			ret = 0;
 		EVP_CIPHER_CTX_cleanup(&ctx);
+		if (ret == 0)
+			goto err;
 		i+=j;
-		ret=1;
 		}
 	else
 		{
@@ -459,14 +463,17 @@ int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
 	ebcdic2ascii(buf, buf, klen);
 #endif
 
-	EVP_BytesToKey(cipher->cipher,EVP_md5(),&(cipher->iv[0]),
-		(unsigned char *)buf,klen,1,key,NULL);
+	if (!EVP_BytesToKey(cipher->cipher,EVP_md5(),&(cipher->iv[0]),
+		(unsigned char *)buf,klen,1,key,NULL))
+		return 0;
 
 	j=(int)len;
 	EVP_CIPHER_CTX_init(&ctx);
-	EVP_DecryptInit_ex(&ctx,cipher->cipher,NULL, key,&(cipher->iv[0]));
-	EVP_DecryptUpdate(&ctx,data,&i,data,j);
-	o=EVP_DecryptFinal_ex(&ctx,&(data[i]),&j);
+	o = EVP_DecryptInit_ex(&ctx,cipher->cipher,NULL, key,&(cipher->iv[0]));
+	if (o)
+		o = EVP_DecryptUpdate(&ctx,data,&i,data,j);
+	if (o)
+		o = EVP_DecryptFinal_ex(&ctx,&(data[i]),&j);
 	EVP_CIPHER_CTX_cleanup(&ctx);
 	OPENSSL_cleanse((char *)buf,sizeof(buf));
 	OPENSSL_cleanse((char *)key,sizeof(key));
diff --git a/src/lib/libcrypto/pem/pem_seal.c b/src/lib/libcrypto/pem/pem_seal.c
index 59690b56ae..b6b4e13498 100644
--- a/src/lib/libcrypto/pem/pem_seal.c
+++ b/src/lib/libcrypto/pem/pem_seal.c
@@ -96,7 +96,8 @@ int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type,
 	EVP_EncodeInit(&ctx->encode);
 
 	EVP_MD_CTX_init(&ctx->md);
-	EVP_SignInit(&ctx->md,md_type);
+	if (!EVP_SignInit(&ctx->md,md_type))
+		goto err;
 
 	EVP_CIPHER_CTX_init(&ctx->cipher);
 	ret=EVP_SealInit(&ctx->cipher,type,ek,ekl,iv,pubk,npubk);
@@ -163,7 +164,8 @@ int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl,
 		goto err;
 		}
 
-	EVP_EncryptFinal_ex(&ctx->cipher,s,(int *)&i);
+	if (!EVP_EncryptFinal_ex(&ctx->cipher,s,(int *)&i))
+		goto err;
 	EVP_EncodeUpdate(&ctx->encode,out,&j,s,i);
 	*outl=j;
 	out+=j;
diff --git a/src/lib/libcrypto/perlasm/cbc.pl b/src/lib/libcrypto/perlasm/cbc.pl
index 6fc2510905..24561e759a 100644
--- a/src/lib/libcrypto/perlasm/cbc.pl
+++ b/src/lib/libcrypto/perlasm/cbc.pl
@@ -150,7 +150,7 @@ sub cbc
 &set_label("PIC_point");
 	&blindpop("edx");
 	&lea("ecx",&DWP(&label("cbc_enc_jmp_table")."-".&label("PIC_point"),"edx"));
-	&mov($count,&DWP(0,"ecx",$count,4))
+	&mov($count,&DWP(0,"ecx",$count,4));
 	&add($count,"edx");
 	&xor("ecx","ecx");
 	&xor("edx","edx");
diff --git a/src/lib/libcrypto/pkcs12/p12_crt.c b/src/lib/libcrypto/pkcs12/p12_crt.c
index 96b131defa..a34915d02d 100644
--- a/src/lib/libcrypto/pkcs12/p12_crt.c
+++ b/src/lib/libcrypto/pkcs12/p12_crt.c
@@ -90,7 +90,14 @@ PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
 
 	/* Set defaults */
 	if (!nid_cert)
+		{
+#ifdef OPENSSL_FIPS
+		if (FIPS_mode())
+			nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+		else
+#endif
 		nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;
+		}
 	if (!nid_key)
 		nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
 	if (!iter)
diff --git a/src/lib/libcrypto/pkcs12/p12_key.c b/src/lib/libcrypto/pkcs12/p12_key.c
index c55c7b60b3..61d58502fd 100644
--- a/src/lib/libcrypto/pkcs12/p12_key.c
+++ b/src/lib/libcrypto/pkcs12/p12_key.c
@@ -176,24 +176,32 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
 		out += u;
 		for (j = 0; j < v; j++) B[j] = Ai[j % u];
 		/* Work out B + 1 first then can use B as tmp space */
-		if (!BN_bin2bn (B, v, Bpl1)) goto err;
-		if (!BN_add_word (Bpl1, 1)) goto err;
+		if (!BN_bin2bn (B, v, Bpl1))
+			goto err;
+		if (!BN_add_word (Bpl1, 1))
+			goto err;
 		for (j = 0; j < Ilen ; j+=v) {
-			if (!BN_bin2bn (I + j, v, Ij)) goto err;
-			if (!BN_add (Ij, Ij, Bpl1)) goto err;
-			BN_bn2bin (Ij, B);
+			if (!BN_bin2bn(I + j, v, Ij))
+				goto err;
+			if (!BN_add(Ij, Ij, Bpl1))
+				goto err;
+			if (!BN_bn2bin(Ij, B))
+				goto err;
 			Ijlen = BN_num_bytes (Ij);
 			/* If more than 2^(v*8) - 1 cut off MSB */
 			if (Ijlen > v) {
-				BN_bn2bin (Ij, B);
+				if (!BN_bn2bin (Ij, B))
+					goto err;
 				memcpy (I + j, B + 1, v);
 #ifndef PKCS12_BROKEN_KEYGEN
 			/* If less than v bytes pad with zeroes */
 			} else if (Ijlen < v) {
 				memset(I + j, 0, v - Ijlen);
-				BN_bn2bin(Ij, I + j + v - Ijlen); 
+				if (!BN_bn2bin(Ij, I + j + v - Ijlen))
+					goto err;
 #endif
-			} else BN_bn2bin (Ij, I + j);
+			} else if (!BN_bn2bin (Ij, I + j))
+				goto err;
 		}
 	}
 
diff --git a/src/lib/libcrypto/pkcs7/bio_pk7.c b/src/lib/libcrypto/pkcs7/bio_pk7.c
index c8d06d6cdc..0fd31e730f 100644
--- a/src/lib/libcrypto/pkcs7/bio_pk7.c
+++ b/src/lib/libcrypto/pkcs7/bio_pk7.c
@@ -56,7 +56,7 @@
 #include <openssl/pkcs7.h>
 #include <openssl/bio.h>
 
-#ifndef OPENSSL_SYSNAME_NETWARE
+#if !defined(OPENSSL_SYSNAME_NETWARE) && !defined(OPENSSL_SYSNAME_VXWORKS)
 #include <memory.h>
 #endif
 #include <stdio.h>
diff --git a/src/lib/libcrypto/ppccap.c b/src/lib/libcrypto/ppccap.c
index ab89ccaa12..f71ba66aa3 100644
--- a/src/lib/libcrypto/ppccap.c
+++ b/src/lib/libcrypto/ppccap.c
@@ -3,6 +3,7 @@
 #include <string.h>
 #include <setjmp.h>
 #include <signal.h>
+#include <unistd.h>
 #include <crypto.h>
 #include <openssl/bn.h>
 
@@ -53,6 +54,7 @@ static sigjmp_buf ill_jmp;
 static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
 
 void OPENSSL_ppc64_probe(void);
+void OPENSSL_altivec_probe(void);
 
 void OPENSSL_cpuid_setup(void)
 	{
@@ -82,6 +84,15 @@ void OPENSSL_cpuid_setup(void)
 
 	OPENSSL_ppccap_P = 0;
 
+#if defined(_AIX)
+	if (sizeof(size_t)==4
+# if defined(_SC_AIX_KERNEL_BITMODE)
+	    && sysconf(_SC_AIX_KERNEL_BITMODE)!=64
+# endif
+	   )
+		return;
+#endif
+
 	memset(&ill_act,0,sizeof(ill_act));
 	ill_act.sa_handler = ill_handler;
 	ill_act.sa_mask    = all_masked;
diff --git a/src/lib/libcrypto/rand/rand.h b/src/lib/libcrypto/rand/rand.h
index dc8fcf94c5..bb5520e80a 100644
--- a/src/lib/libcrypto/rand/rand.h
+++ b/src/lib/libcrypto/rand/rand.h
@@ -138,6 +138,7 @@ void ERR_load_RAND_strings(void);
 #define RAND_F_SSLEAY_RAND_BYTES			 100
 
 /* Reason codes. */
+#define RAND_R_DUAL_EC_DRBG_DISABLED			 104
 #define RAND_R_ERROR_INITIALISING_DRBG			 102
 #define RAND_R_ERROR_INSTANTIATING_DRBG			 103
 #define RAND_R_NO_FIPS_RANDOM_METHOD_SET		 101
diff --git a/src/lib/libcrypto/rand/rand_err.c b/src/lib/libcrypto/rand/rand_err.c
index b8586c8f4a..c4c80fc8cc 100644
--- a/src/lib/libcrypto/rand/rand_err.c
+++ b/src/lib/libcrypto/rand/rand_err.c
@@ -78,6 +78,7 @@ static ERR_STRING_DATA RAND_str_functs[]=
 
 static ERR_STRING_DATA RAND_str_reasons[]=
 	{
+{ERR_REASON(RAND_R_DUAL_EC_DRBG_DISABLED),"dual ec drbg disabled"},
 {ERR_REASON(RAND_R_ERROR_INITIALISING_DRBG),"error initialising drbg"},
 {ERR_REASON(RAND_R_ERROR_INSTANTIATING_DRBG),"error instantiating drbg"},
 {ERR_REASON(RAND_R_NO_FIPS_RANDOM_METHOD_SET),"no fips random method set"},
diff --git a/src/lib/libcrypto/rand/rand_lib.c b/src/lib/libcrypto/rand/rand_lib.c
index daf1dab973..5ac0e14caf 100644
--- a/src/lib/libcrypto/rand/rand_lib.c
+++ b/src/lib/libcrypto/rand/rand_lib.c
@@ -210,8 +210,11 @@ static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout,
 
 static void drbg_free_entropy(DRBG_CTX *ctx, unsigned char *out, size_t olen)
 	{
-	OPENSSL_cleanse(out, olen);
-	OPENSSL_free(out);
+	if (out)
+		{
+		OPENSSL_cleanse(out, olen);
+		OPENSSL_free(out);
+		}
 	}
 
 /* Set "additional input" when generating random data. This uses the
@@ -266,6 +269,14 @@ int RAND_init_fips(void)
 	DRBG_CTX *dctx;
 	size_t plen;
 	unsigned char pers[32], *p;
+#ifndef OPENSSL_ALLOW_DUAL_EC_DRBG
+	if (fips_drbg_type >> 16)
+		{
+		RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_DUAL_EC_DRBG_DISABLED);
+		return 0;
+		}
+#endif
+		
 	dctx = FIPS_get_default_drbg();
         if (FIPS_drbg_init(dctx, fips_drbg_type, fips_drbg_flags) <= 0)
 		{
diff --git a/src/lib/libcrypto/rand/randfile.c b/src/lib/libcrypto/rand/randfile.c
index 030e07f418..7f1428072d 100644
--- a/src/lib/libcrypto/rand/randfile.c
+++ b/src/lib/libcrypto/rand/randfile.c
@@ -57,7 +57,9 @@
  */
 
 /* We need to define this to get macros like S_IFBLK and S_IFCHR */
+#if !defined(OPENSSL_SYS_VXWORKS)
 #define _XOPEN_SOURCE 500
+#endif
 
 #include <errno.h>
 #include <stdio.h>
diff --git a/src/lib/libcrypto/rc4/asm/rc4-md5-x86_64.pl b/src/lib/libcrypto/rc4/asm/rc4-md5-x86_64.pl
index 7f684092d4..272fa91e1a 100644
--- a/src/lib/libcrypto/rc4/asm/rc4-md5-x86_64.pl
+++ b/src/lib/libcrypto/rc4/asm/rc4-md5-x86_64.pl
@@ -51,7 +51,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 my ($dat,$in0,$out,$ctx,$inp,$len, $func,$nargs);
 
diff --git a/src/lib/libcrypto/rc4/asm/rc4-parisc.pl b/src/lib/libcrypto/rc4/asm/rc4-parisc.pl
index 9165067080..ad7e65651c 100644
--- a/src/lib/libcrypto/rc4/asm/rc4-parisc.pl
+++ b/src/lib/libcrypto/rc4/asm/rc4-parisc.pl
@@ -307,7 +307,8 @@ L\$opts
 	.STRINGZ "RC4 for PA-RISC, CRYPTOGAMS by <appro\@openssl.org>"
 ___
 $code =~ s/\`([^\`]*)\`/eval $1/gem;
-$code =~ s/cmpib,\*/comib,/gm if ($SIZE_T==4);
+$code =~ s/cmpib,\*/comib,/gm	if ($SIZE_T==4);
+$code =~ s/\bbv\b/bve/gm	if ($SIZE_T==8);
 
 print $code;
 close STDOUT;
diff --git a/src/lib/libcrypto/rc4/asm/rc4-x86_64.pl b/src/lib/libcrypto/rc4/asm/rc4-x86_64.pl
index d6eac205e9..75750dbf33 100755
--- a/src/lib/libcrypto/rc4/asm/rc4-x86_64.pl
+++ b/src/lib/libcrypto/rc4/asm/rc4-x86_64.pl
@@ -112,7 +112,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 $dat="%rdi";	    # arg1
 $len="%rsi";	    # arg2
diff --git a/src/lib/libcrypto/ripemd/rmd_dgst.c b/src/lib/libcrypto/ripemd/rmd_dgst.c
index 63f0d983f7..d8e72da51b 100644
--- a/src/lib/libcrypto/ripemd/rmd_dgst.c
+++ b/src/lib/libcrypto/ripemd/rmd_dgst.c
@@ -105,21 +105,21 @@ void ripemd160_block_data_order (RIPEMD160_CTX *ctx, const void *p, size_t num)
 
 	A=ctx->A; B=ctx->B; C=ctx->C; D=ctx->D; E=ctx->E;
 
-	HOST_c2l(data,l); X( 0)=l;	HOST_c2l(data,l); X( 1)=l;
-	RIP1(A,B,C,D,E,WL00,SL00);	HOST_c2l(data,l); X( 2)=l;
-	RIP1(E,A,B,C,D,WL01,SL01);	HOST_c2l(data,l); X( 3)=l;
-	RIP1(D,E,A,B,C,WL02,SL02);	HOST_c2l(data,l); X( 4)=l;
-	RIP1(C,D,E,A,B,WL03,SL03);	HOST_c2l(data,l); X( 5)=l;
-	RIP1(B,C,D,E,A,WL04,SL04);	HOST_c2l(data,l); X( 6)=l;
-	RIP1(A,B,C,D,E,WL05,SL05);	HOST_c2l(data,l); X( 7)=l;
-	RIP1(E,A,B,C,D,WL06,SL06);	HOST_c2l(data,l); X( 8)=l;
-	RIP1(D,E,A,B,C,WL07,SL07);	HOST_c2l(data,l); X( 9)=l;
-	RIP1(C,D,E,A,B,WL08,SL08);	HOST_c2l(data,l); X(10)=l;
-	RIP1(B,C,D,E,A,WL09,SL09);	HOST_c2l(data,l); X(11)=l;
-	RIP1(A,B,C,D,E,WL10,SL10);	HOST_c2l(data,l); X(12)=l;
-	RIP1(E,A,B,C,D,WL11,SL11);	HOST_c2l(data,l); X(13)=l;
-	RIP1(D,E,A,B,C,WL12,SL12);	HOST_c2l(data,l); X(14)=l;
-	RIP1(C,D,E,A,B,WL13,SL13);	HOST_c2l(data,l); X(15)=l;
+	(void)HOST_c2l(data,l); X( 0)=l;(void)HOST_c2l(data,l); X( 1)=l;
+	RIP1(A,B,C,D,E,WL00,SL00);	(void)HOST_c2l(data,l); X( 2)=l;
+	RIP1(E,A,B,C,D,WL01,SL01);	(void)HOST_c2l(data,l); X( 3)=l;
+	RIP1(D,E,A,B,C,WL02,SL02);	(void)HOST_c2l(data,l); X( 4)=l;
+	RIP1(C,D,E,A,B,WL03,SL03);	(void)HOST_c2l(data,l); X( 5)=l;
+	RIP1(B,C,D,E,A,WL04,SL04);	(void)HOST_c2l(data,l); X( 6)=l;
+	RIP1(A,B,C,D,E,WL05,SL05);	(void)HOST_c2l(data,l); X( 7)=l;
+	RIP1(E,A,B,C,D,WL06,SL06);	(void)HOST_c2l(data,l); X( 8)=l;
+	RIP1(D,E,A,B,C,WL07,SL07);	(void)HOST_c2l(data,l); X( 9)=l;
+	RIP1(C,D,E,A,B,WL08,SL08);	(void)HOST_c2l(data,l); X(10)=l;
+	RIP1(B,C,D,E,A,WL09,SL09);	(void)HOST_c2l(data,l); X(11)=l;
+	RIP1(A,B,C,D,E,WL10,SL10);	(void)HOST_c2l(data,l); X(12)=l;
+	RIP1(E,A,B,C,D,WL11,SL11);	(void)HOST_c2l(data,l); X(13)=l;
+	RIP1(D,E,A,B,C,WL12,SL12);	(void)HOST_c2l(data,l); X(14)=l;
+	RIP1(C,D,E,A,B,WL13,SL13);	(void)HOST_c2l(data,l); X(15)=l;
 	RIP1(B,C,D,E,A,WL14,SL14);
 	RIP1(A,B,C,D,E,WL15,SL15);
 
diff --git a/src/lib/libcrypto/ripemd/rmd_locl.h b/src/lib/libcrypto/ripemd/rmd_locl.h
index f14b346e66..2bd8957d14 100644
--- a/src/lib/libcrypto/ripemd/rmd_locl.h
+++ b/src/lib/libcrypto/ripemd/rmd_locl.h
@@ -88,11 +88,11 @@ void ripemd160_block_data_order (RIPEMD160_CTX *c, const void *p,size_t num);
 #define HASH_FINAL              RIPEMD160_Final
 #define	HASH_MAKE_STRING(c,s)	do {	\
 	unsigned long ll;		\
-	ll=(c)->A; HOST_l2c(ll,(s));	\
-	ll=(c)->B; HOST_l2c(ll,(s));	\
-	ll=(c)->C; HOST_l2c(ll,(s));	\
-	ll=(c)->D; HOST_l2c(ll,(s));	\
-	ll=(c)->E; HOST_l2c(ll,(s));	\
+	ll=(c)->A; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->B; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->C; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->D; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->E; (void)HOST_l2c(ll,(s));	\
 	} while (0)
 #define HASH_BLOCK_DATA_ORDER   ripemd160_block_data_order
 
diff --git a/src/lib/libcrypto/rsa/rsa.h b/src/lib/libcrypto/rsa/rsa.h
index 4814a2fc15..5f269e577a 100644
--- a/src/lib/libcrypto/rsa/rsa.h
+++ b/src/lib/libcrypto/rsa/rsa.h
@@ -280,7 +280,7 @@ struct rsa_st
 
 RSA *	RSA_new(void);
 RSA *	RSA_new_method(ENGINE *engine);
-int	RSA_size(const RSA *);
+int	RSA_size(const RSA *rsa);
 
 /* Deprecated version */
 #ifndef OPENSSL_NO_DEPRECATED
diff --git a/src/lib/libcrypto/rsa/rsa_ameth.c b/src/lib/libcrypto/rsa/rsa_ameth.c
index 2460910ab2..5a2062f903 100644
--- a/src/lib/libcrypto/rsa/rsa_ameth.c
+++ b/src/lib/libcrypto/rsa/rsa_ameth.c
@@ -351,27 +351,27 @@ static int rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss,
 
 	if (!BIO_indent(bp, indent, 128))
 		goto err;
-	if (BIO_puts(bp, "Salt Length: ") <= 0)
+	if (BIO_puts(bp, "Salt Length: 0x") <= 0)
 			goto err;
 	if (pss->saltLength)
 		{
 		if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0)
 			goto err;
 		}
-	else if (BIO_puts(bp, "20 (default)") <= 0)
+	else if (BIO_puts(bp, "0x14 (default)") <= 0)
 		goto err;
 	BIO_puts(bp, "\n");
 
 	if (!BIO_indent(bp, indent, 128))
 		goto err;
-	if (BIO_puts(bp, "Trailer Field: ") <= 0)
+	if (BIO_puts(bp, "Trailer Field: 0x") <= 0)
 			goto err;
 	if (pss->trailerField)
 		{
 		if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0)
 			goto err;
 		}
-	else if (BIO_puts(bp, "0xbc (default)") <= 0)
+	else if (BIO_puts(bp, "BC (default)") <= 0)
 		goto err;
 	BIO_puts(bp, "\n");
 	
diff --git a/src/lib/libcrypto/rsa/rsa_chk.c b/src/lib/libcrypto/rsa/rsa_chk.c
index 9d848db8c6..cc30e77132 100644
--- a/src/lib/libcrypto/rsa/rsa_chk.c
+++ b/src/lib/libcrypto/rsa/rsa_chk.c
@@ -59,6 +59,12 @@ int RSA_check_key(const RSA *key)
 	BN_CTX *ctx;
 	int r;
 	int ret=1;
+
+	if (!key->p || !key->q || !key->n || !key->e || !key->d)
+		{
+		RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_VALUE_MISSING);
+		return 0;
+		}
 	
 	i = BN_new();
 	j = BN_new();
diff --git a/src/lib/libcrypto/rsa/rsa_eay.c b/src/lib/libcrypto/rsa/rsa_eay.c
index 2e1ddd48d3..88ee2cb557 100644
--- a/src/lib/libcrypto/rsa/rsa_eay.c
+++ b/src/lib/libcrypto/rsa/rsa_eay.c
@@ -847,12 +847,12 @@ static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
 	if (!BN_mod(r0,pr1,rsa->p,ctx)) goto err;
 
 	/* If p < q it is occasionally possible for the correction of
-         * adding 'p' if r0 is negative above to leave the result still
+	 * adding 'p' if r0 is negative above to leave the result still
 	 * negative. This can break the private key operations: the following
 	 * second correction should *always* correct this rare occurrence.
 	 * This will *never* happen with OpenSSL generated keys because
-         * they ensure p > q [steve]
-         */
+	 * they ensure p > q [steve]
+	 */
 	if (BN_is_negative(r0))
 		if (!BN_add(r0,r0,rsa->p)) goto err;
 	if (!BN_mul(r1,r0,rsa->q,ctx)) goto err;
diff --git a/src/lib/libcrypto/rsa/rsa_oaep.c b/src/lib/libcrypto/rsa/rsa_oaep.c
index 553d212ebe..af4d24a56e 100644
--- a/src/lib/libcrypto/rsa/rsa_oaep.c
+++ b/src/lib/libcrypto/rsa/rsa_oaep.c
@@ -149,7 +149,7 @@ int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
 	if (!EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL))
 		return -1;
 
-	if (memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
+	if (CRYPTO_memcmp(db, phash, SHA_DIGEST_LENGTH) != 0 || bad)
 		goto decoding_err;
 	else
 		{
diff --git a/src/lib/libcrypto/rsa/rsa_pmeth.c b/src/lib/libcrypto/rsa/rsa_pmeth.c
index 5b2ecf56ad..157aa5c41d 100644
--- a/src/lib/libcrypto/rsa/rsa_pmeth.c
+++ b/src/lib/libcrypto/rsa/rsa_pmeth.c
@@ -611,6 +611,8 @@ static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
 			pm = RSA_NO_PADDING;
 		else if (!strcmp(value, "oeap"))
 			pm = RSA_PKCS1_OAEP_PADDING;
+		else if (!strcmp(value, "oaep"))
+			pm = RSA_PKCS1_OAEP_PADDING;
 		else if (!strcmp(value, "x931"))
 			pm = RSA_X931_PADDING;
 		else if (!strcmp(value, "pss"))
diff --git a/src/lib/libcrypto/sha/asm/sha1-armv4-large.pl b/src/lib/libcrypto/sha/asm/sha1-armv4-large.pl
index fe8207f77f..33da3e0e3c 100644
--- a/src/lib/libcrypto/sha/asm/sha1-armv4-large.pl
+++ b/src/lib/libcrypto/sha/asm/sha1-armv4-large.pl
@@ -177,6 +177,7 @@ for($i=0;$i<5;$i++) {
 $code.=<<___;
 	teq	$Xi,sp
 	bne	.L_00_15		@ [((11+4)*5+2)*3]
+	sub	sp,sp,#25*4
 ___
 	&BODY_00_15(@V);	unshift(@V,pop(@V));
 	&BODY_16_19(@V);	unshift(@V,pop(@V));
@@ -186,7 +187,6 @@ ___
 $code.=<<___;
 
 	ldr	$K,.LK_20_39		@ [+15+16*4]
-	sub	sp,sp,#25*4
 	cmn	sp,#0			@ [+3], clear carry to denote 20_39
 .L_20_39_or_60_79:
 ___
diff --git a/src/lib/libcrypto/sha/asm/sha1-ia64.pl b/src/lib/libcrypto/sha/asm/sha1-ia64.pl
index db28f0805a..02d35d1614 100644
--- a/src/lib/libcrypto/sha/asm/sha1-ia64.pl
+++ b/src/lib/libcrypto/sha/asm/sha1-ia64.pl
@@ -271,7 +271,8 @@ tmp6=loc13;
 
 ___
 
-{ my $i,@V=($A,$B,$C,$D,$E);
+{ my $i;
+  my @V=($A,$B,$C,$D,$E);
 
 	for($i=0;$i<16;$i++)	{ &BODY_00_15(\$code,$i,@V); unshift(@V,pop(@V)); }
 	for(;$i<20;$i++)	{ &BODY_16_19(\$code,$i,@V); unshift(@V,pop(@V)); }
diff --git a/src/lib/libcrypto/sha/asm/sha1-parisc.pl b/src/lib/libcrypto/sha/asm/sha1-parisc.pl
index 6d7bf495b2..6e5a328a6f 100644
--- a/src/lib/libcrypto/sha/asm/sha1-parisc.pl
+++ b/src/lib/libcrypto/sha/asm/sha1-parisc.pl
@@ -254,6 +254,7 @@ $code.=<<___;
 ___
 
 $code =~ s/\`([^\`]*)\`/eval $1/gem;
-$code =~ s/,\*/,/gm if ($SIZE_T==4);
+$code =~ s/,\*/,/gm		if ($SIZE_T==4);
+$code =~ s/\bbv\b/bve/gm	if ($SIZE_T==8);
 print $code;
 close STDOUT;
diff --git a/src/lib/libcrypto/sha/asm/sha1-sparcv9a.pl b/src/lib/libcrypto/sha/asm/sha1-sparcv9a.pl
index 85e8d68086..e65291bbd9 100644
--- a/src/lib/libcrypto/sha/asm/sha1-sparcv9a.pl
+++ b/src/lib/libcrypto/sha/asm/sha1-sparcv9a.pl
@@ -549,7 +549,7 @@ ___
 # programmer detect if current CPU is VIS capable at run-time.
 sub unvis {
 my ($mnemonic,$rs1,$rs2,$rd)=@_;
-my $ref,$opf;
+my ($ref,$opf);
 my %visopf = (	"fmul8ulx16"	=> 0x037,
 		"faligndata"	=> 0x048,
 		"fpadd32"	=> 0x052,
diff --git a/src/lib/libcrypto/sha/asm/sha1-x86_64.pl b/src/lib/libcrypto/sha/asm/sha1-x86_64.pl
index f27c1e3fb0..f15c7ec39b 100755
--- a/src/lib/libcrypto/sha/asm/sha1-x86_64.pl
+++ b/src/lib/libcrypto/sha/asm/sha1-x86_64.pl
@@ -82,7 +82,8 @@ $avx=1 if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
 	   `ml64 2>&1` =~ /Version ([0-9]+)\./ &&
 	   $1>=10);
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 $ctx="%rdi";	# 1st arg
 $inp="%rsi";	# 2nd arg
@@ -744,7 +745,7 @@ $code.=<<___;
 	mov	%rdi,$ctx	# reassigned argument
 	mov	%rsi,$inp	# reassigned argument
 	mov	%rdx,$num	# reassigned argument
-	vzeroall
+	vzeroupper
 
 	shl	\$6,$num
 	add	$inp,$num
@@ -1037,7 +1038,7 @@ ___
 	&Xtail_avx(\&body_20_39);
 
 $code.=<<___;
-	vzeroall
+	vzeroupper
 
 	add	0($ctx),$A			# update context
 	add	4($ctx),@T[0]
diff --git a/src/lib/libcrypto/sha/asm/sha512-586.pl b/src/lib/libcrypto/sha/asm/sha512-586.pl
index 5b9f3337ad..7eab6a5b88 100644
--- a/src/lib/libcrypto/sha/asm/sha512-586.pl
+++ b/src/lib/libcrypto/sha/asm/sha512-586.pl
@@ -142,9 +142,9 @@ sub BODY_00_15_x86 {
 	&mov	("edx",$Ehi);
 	&mov	("esi","ecx");
 
-	&shr	("ecx",9)	# lo>>9
+	&shr	("ecx",9);	# lo>>9
 	&mov	("edi","edx");
-	&shr	("edx",9)	# hi>>9
+	&shr	("edx",9);	# hi>>9
 	&mov	("ebx","ecx");
 	&shl	("esi",14);	# lo<<14
 	&mov	("eax","edx");
@@ -207,9 +207,9 @@ sub BODY_00_15_x86 {
 	&mov	($Dhi,"ebx");
 	&mov	("esi","ecx");
 
-	&shr	("ecx",2)	# lo>>2
+	&shr	("ecx",2);	# lo>>2
 	&mov	("edi","edx");
-	&shr	("edx",2)	# hi>>2
+	&shr	("edx",2);	# hi>>2
 	&mov	("ebx","ecx");
 	&shl	("esi",4);	# lo<<4
 	&mov	("eax","edx");
@@ -452,9 +452,9 @@ if ($sse2) {
 	&mov	("edx",&DWP(8*(9+15+16-1)+4,"esp"));
 	&mov	("esi","ecx");
 
-	&shr	("ecx",1)	# lo>>1
+	&shr	("ecx",1);	# lo>>1
 	&mov	("edi","edx");
-	&shr	("edx",1)	# hi>>1
+	&shr	("edx",1);	# hi>>1
 	&mov	("eax","ecx");
 	&shl	("esi",24);	# lo<<24
 	&mov	("ebx","edx");
@@ -488,9 +488,9 @@ if ($sse2) {
 	&mov	("edx",&DWP(8*(9+15+16-14)+4,"esp"));
 	&mov	("esi","ecx");
 
-	&shr	("ecx",6)	# lo>>6
+	&shr	("ecx",6);	# lo>>6
 	&mov	("edi","edx");
-	&shr	("edx",6)	# hi>>6
+	&shr	("edx",6);	# hi>>6
 	&mov	("eax","ecx");
 	&shl	("esi",3);	# lo<<3
 	&mov	("ebx","edx");
diff --git a/src/lib/libcrypto/sha/asm/sha512-mips.pl b/src/lib/libcrypto/sha/asm/sha512-mips.pl
index ba5b250890..ffa053bb7d 100644
--- a/src/lib/libcrypto/sha/asm/sha512-mips.pl
+++ b/src/lib/libcrypto/sha/asm/sha512-mips.pl
@@ -351,7 +351,7 @@ $code.=<<___;
 	$ST	$G,6*$SZ($ctx)
 	$ST	$H,7*$SZ($ctx)
 
-	bnel	$inp,@X[15],.Loop
+	bne	$inp,@X[15],.Loop
 	$PTR_SUB $Ktbl,`($rounds-16)*$SZ`	# rewind $Ktbl
 
 	$REG_L	$ra,$FRAMESIZE-1*$SZREG($sp)
diff --git a/src/lib/libcrypto/sha/asm/sha512-parisc.pl b/src/lib/libcrypto/sha/asm/sha512-parisc.pl
index e24ee58ae9..fc0e15b3c0 100755
--- a/src/lib/libcrypto/sha/asm/sha512-parisc.pl
+++ b/src/lib/libcrypto/sha/asm/sha512-parisc.pl
@@ -785,6 +785,8 @@ foreach (split("\n",$code)) {
 
 	s/cmpb,\*/comb,/ if ($SIZE_T==4);
 
+	s/\bbv\b/bve/    if ($SIZE_T==8);
+
 	print $_,"\n";
 }
 
diff --git a/src/lib/libcrypto/sha/asm/sha512-x86_64.pl b/src/lib/libcrypto/sha/asm/sha512-x86_64.pl
index f611a2d898..8d51678557 100755
--- a/src/lib/libcrypto/sha/asm/sha512-x86_64.pl
+++ b/src/lib/libcrypto/sha/asm/sha512-x86_64.pl
@@ -51,7 +51,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 if ($output =~ /512/) {
 	$func="sha512_block_data_order";
diff --git a/src/lib/libcrypto/sha/sha1_one.c b/src/lib/libcrypto/sha/sha1_one.c
index 7c65b60276..c56ec94020 100644
--- a/src/lib/libcrypto/sha/sha1_one.c
+++ b/src/lib/libcrypto/sha/sha1_one.c
@@ -58,8 +58,8 @@
 
 #include <stdio.h>
 #include <string.h>
-#include <openssl/sha.h>
 #include <openssl/crypto.h>
+#include <openssl/sha.h>
 
 #ifndef OPENSSL_NO_SHA1
 unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md)
diff --git a/src/lib/libcrypto/sha/sha1dgst.c b/src/lib/libcrypto/sha/sha1dgst.c
index 81219af088..a98690225f 100644
--- a/src/lib/libcrypto/sha/sha1dgst.c
+++ b/src/lib/libcrypto/sha/sha1dgst.c
@@ -56,8 +56,8 @@
  * [including the GNU Public Licence.]
  */
 
-#include <openssl/opensslconf.h>
 #include <openssl/crypto.h>
+#include <openssl/opensslconf.h>
 #if !defined(OPENSSL_NO_SHA1) && !defined(OPENSSL_NO_SHA)
 
 #undef  SHA_0
diff --git a/src/lib/libcrypto/sha/sha256.c b/src/lib/libcrypto/sha/sha256.c
index f88d3d6dad..4eae074849 100644
--- a/src/lib/libcrypto/sha/sha256.c
+++ b/src/lib/libcrypto/sha/sha256.c
@@ -88,17 +88,17 @@ int SHA224_Final (unsigned char *md, SHA256_CTX *c)
 	switch ((c)->md_len)		\
 	{   case SHA224_DIGEST_LENGTH:	\
 		for (nn=0;nn<SHA224_DIGEST_LENGTH/4;nn++)	\
-		{   ll=(c)->h[nn]; HOST_l2c(ll,(s));   }	\
+		{   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }	\
 		break;			\
 	    case SHA256_DIGEST_LENGTH:	\
 		for (nn=0;nn<SHA256_DIGEST_LENGTH/4;nn++)	\
-		{   ll=(c)->h[nn]; HOST_l2c(ll,(s));   }	\
+		{   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }	\
 		break;			\
 	    default:			\
 		if ((c)->md_len > SHA256_DIGEST_LENGTH)	\
 		    return 0;				\
 		for (nn=0;nn<(c)->md_len/4;nn++)		\
-		{   ll=(c)->h[nn]; HOST_l2c(ll,(s));   }	\
+		{   ll=(c)->h[nn]; (void)HOST_l2c(ll,(s));   }	\
 		break;			\
 	}				\
 	} while (0)
diff --git a/src/lib/libcrypto/sha/sha512.c b/src/lib/libcrypto/sha/sha512.c
index 50dd7dc744..50c229ddeb 100644
--- a/src/lib/libcrypto/sha/sha512.c
+++ b/src/lib/libcrypto/sha/sha512.c
@@ -232,7 +232,14 @@ int SHA384_Update (SHA512_CTX *c, const void *data, size_t len)
 {   return SHA512_Update (c,data,len);   }
 
 void SHA512_Transform (SHA512_CTX *c, const unsigned char *data)
-{   sha512_block_data_order (c,data,1);  }
+	{
+#ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA
+	if ((size_t)data%sizeof(c->u.d[0]) != 0)
+		memcpy(c->u.p,data,sizeof(c->u.p)),
+		data = c->u.p;
+#endif
+	sha512_block_data_order (c,data,1);
+	}
 
 unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md)
 	{
diff --git a/src/lib/libcrypto/sha/sha_locl.h b/src/lib/libcrypto/sha/sha_locl.h
index 7a0c3ca8d8..d673255f78 100644
--- a/src/lib/libcrypto/sha/sha_locl.h
+++ b/src/lib/libcrypto/sha/sha_locl.h
@@ -69,11 +69,11 @@
 #define HASH_CBLOCK             SHA_CBLOCK
 #define HASH_MAKE_STRING(c,s)   do {	\
 	unsigned long ll;		\
-	ll=(c)->h0; HOST_l2c(ll,(s));	\
-	ll=(c)->h1; HOST_l2c(ll,(s));	\
-	ll=(c)->h2; HOST_l2c(ll,(s));	\
-	ll=(c)->h3; HOST_l2c(ll,(s));	\
-	ll=(c)->h4; HOST_l2c(ll,(s));	\
+	ll=(c)->h0; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->h1; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->h2; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->h3; (void)HOST_l2c(ll,(s));	\
+	ll=(c)->h4; (void)HOST_l2c(ll,(s));	\
 	} while (0)
 
 #if defined(SHA_0)
@@ -256,21 +256,21 @@ static void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, size_t num)
 		}
 	else
 		{
-		HOST_c2l(data,l); X( 0)=l;		HOST_c2l(data,l); X( 1)=l;
-		BODY_00_15( 0,A,B,C,D,E,T,X( 0));	HOST_c2l(data,l); X( 2)=l;
-		BODY_00_15( 1,T,A,B,C,D,E,X( 1));	HOST_c2l(data,l); X( 3)=l;
-		BODY_00_15( 2,E,T,A,B,C,D,X( 2));	HOST_c2l(data,l); X( 4)=l;
-		BODY_00_15( 3,D,E,T,A,B,C,X( 3));	HOST_c2l(data,l); X( 5)=l;
-		BODY_00_15( 4,C,D,E,T,A,B,X( 4));	HOST_c2l(data,l); X( 6)=l;
-		BODY_00_15( 5,B,C,D,E,T,A,X( 5));	HOST_c2l(data,l); X( 7)=l;
-		BODY_00_15( 6,A,B,C,D,E,T,X( 6));	HOST_c2l(data,l); X( 8)=l;
-		BODY_00_15( 7,T,A,B,C,D,E,X( 7));	HOST_c2l(data,l); X( 9)=l;
-		BODY_00_15( 8,E,T,A,B,C,D,X( 8));	HOST_c2l(data,l); X(10)=l;
-		BODY_00_15( 9,D,E,T,A,B,C,X( 9));	HOST_c2l(data,l); X(11)=l;
-		BODY_00_15(10,C,D,E,T,A,B,X(10));	HOST_c2l(data,l); X(12)=l;
-		BODY_00_15(11,B,C,D,E,T,A,X(11));	HOST_c2l(data,l); X(13)=l;
-		BODY_00_15(12,A,B,C,D,E,T,X(12));	HOST_c2l(data,l); X(14)=l;
-		BODY_00_15(13,T,A,B,C,D,E,X(13));	HOST_c2l(data,l); X(15)=l;
+		(void)HOST_c2l(data,l); X( 0)=l;	(void)HOST_c2l(data,l); X( 1)=l;
+		BODY_00_15( 0,A,B,C,D,E,T,X( 0));	(void)HOST_c2l(data,l); X( 2)=l;
+		BODY_00_15( 1,T,A,B,C,D,E,X( 1));	(void)HOST_c2l(data,l); X( 3)=l;
+		BODY_00_15( 2,E,T,A,B,C,D,X( 2));	(void)HOST_c2l(data,l); X( 4)=l;
+		BODY_00_15( 3,D,E,T,A,B,C,X( 3));	(void)HOST_c2l(data,l); X( 5)=l;
+		BODY_00_15( 4,C,D,E,T,A,B,X( 4));	(void)HOST_c2l(data,l); X( 6)=l;
+		BODY_00_15( 5,B,C,D,E,T,A,X( 5));	(void)HOST_c2l(data,l); X( 7)=l;
+		BODY_00_15( 6,A,B,C,D,E,T,X( 6));	(void)HOST_c2l(data,l); X( 8)=l;
+		BODY_00_15( 7,T,A,B,C,D,E,X( 7));	(void)HOST_c2l(data,l); X( 9)=l;
+		BODY_00_15( 8,E,T,A,B,C,D,X( 8));	(void)HOST_c2l(data,l); X(10)=l;
+		BODY_00_15( 9,D,E,T,A,B,C,X( 9));	(void)HOST_c2l(data,l); X(11)=l;
+		BODY_00_15(10,C,D,E,T,A,B,X(10));	(void)HOST_c2l(data,l); X(12)=l;
+		BODY_00_15(11,B,C,D,E,T,A,X(11));	(void)HOST_c2l(data,l); X(13)=l;
+		BODY_00_15(12,A,B,C,D,E,T,X(12));	(void)HOST_c2l(data,l); X(14)=l;
+		BODY_00_15(13,T,A,B,C,D,E,X(13));	(void)HOST_c2l(data,l); X(15)=l;
 		BODY_00_15(14,E,T,A,B,C,D,X(14));
 		BODY_00_15(15,D,E,T,A,B,C,X(15));
 		}
diff --git a/src/lib/libcrypto/sparccpuid.S b/src/lib/libcrypto/sparccpuid.S
index ae61f7f5ce..0cc247e489 100644
--- a/src/lib/libcrypto/sparccpuid.S
+++ b/src/lib/libcrypto/sparccpuid.S
@@ -235,10 +235,10 @@ _sparcv9_rdtick:
 .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/src/lib/libcrypto/ui/ui_openssl.c b/src/lib/libcrypto/ui/ui_openssl.c
index 5832a73cf5..a38c7581e6 100644
--- a/src/lib/libcrypto/ui/ui_openssl.c
+++ b/src/lib/libcrypto/ui/ui_openssl.c
@@ -122,9 +122,15 @@
  * sigaction and fileno included. -pedantic would be more appropriate for
  * the intended purposes, but we can't prevent users from adding -ansi.
  */
+#if defined(OPENSSL_SYSNAME_VXWORKS)
+#include <sys/types.h>
+#endif
+
 #if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
+#ifndef _POSIX_C_SOURCE
 #define _POSIX_C_SOURCE 2
 #endif
+#endif
 #include <signal.h>
 #include <stdio.h>
 #include <string.h>
diff --git a/src/lib/libcrypto/whrlpool/asm/wp-mmx.pl b/src/lib/libcrypto/whrlpool/asm/wp-mmx.pl
index 32cf16380b..cb2381c22b 100644
--- a/src/lib/libcrypto/whrlpool/asm/wp-mmx.pl
+++ b/src/lib/libcrypto/whrlpool/asm/wp-mmx.pl
@@ -119,7 +119,7 @@ $tbl="ebp";
 	&mov	("eax",&DWP(0,"esp"));
 	&mov	("ebx",&DWP(4,"esp"));
 for($i=0;$i<8;$i++) {
-    my $func = ($i==0)? movq : pxor;
+    my $func = ($i==0)? \&movq : \&pxor;
 	&movb	(&LB("ecx"),&LB("eax"));
 	&movb	(&LB("edx"),&HB("eax"));
 	&scale	("esi","ecx");
diff --git a/src/lib/libcrypto/whrlpool/asm/wp-x86_64.pl b/src/lib/libcrypto/whrlpool/asm/wp-x86_64.pl
index 87c0843dc1..24b2ff60c3 100644
--- a/src/lib/libcrypto/whrlpool/asm/wp-x86_64.pl
+++ b/src/lib/libcrypto/whrlpool/asm/wp-x86_64.pl
@@ -41,7 +41,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 sub L() { $code.=".byte	".join(',',@_)."\n"; }
 sub LL(){ $code.=".byte	".join(',',@_).",".join(',',@_)."\n"; }
diff --git a/src/lib/libcrypto/x509/by_dir.c b/src/lib/libcrypto/x509/by_dir.c
index 27ca5150c1..c6602dae4f 100644
--- a/src/lib/libcrypto/x509/by_dir.c
+++ b/src/lib/libcrypto/x509/by_dir.c
@@ -218,7 +218,7 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
 
 	s=dir;
 	p=s;
-	for (;;p++)
+	do
 		{
 		if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0'))
 			{
@@ -264,9 +264,7 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
 				return 0;
 				}
 			}
-		if (*p == '\0')
-			break;
-		}
+		} while (*p++ != '\0');
 	return 1;
 	}
 
diff --git a/src/lib/libcrypto/x509/x509_cmp.c b/src/lib/libcrypto/x509/x509_cmp.c
index 7c2aaee2e9..352aa37434 100644
--- a/src/lib/libcrypto/x509/x509_cmp.c
+++ b/src/lib/libcrypto/x509/x509_cmp.c
@@ -86,10 +86,9 @@ unsigned long X509_issuer_and_serial_hash(X509 *a)
 
 	EVP_MD_CTX_init(&ctx);
 	f=X509_NAME_oneline(a->cert_info->issuer,NULL,0);
-	ret=strlen(f);
 	if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL))
 		goto err;
-	if (!EVP_DigestUpdate(&ctx,(unsigned char *)f,ret))
+	if (!EVP_DigestUpdate(&ctx,(unsigned char *)f,strlen(f)))
 		goto err;
 	OPENSSL_free(f);
 	if(!EVP_DigestUpdate(&ctx,(unsigned char *)a->cert_info->serialNumber->data,
@@ -249,14 +248,14 @@ unsigned long X509_NAME_hash_old(X509_NAME *x)
 	i2d_X509_NAME(x,NULL);
 	EVP_MD_CTX_init(&md_ctx);
 	EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-	EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL);
-	EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length);
-	EVP_DigestFinal_ex(&md_ctx,md,NULL);
+	if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL)
+	    && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length)
+	    && EVP_DigestFinal_ex(&md_ctx,md,NULL))
+		ret=(((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
+		     ((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
+		     )&0xffffffffL;
 	EVP_MD_CTX_cleanup(&md_ctx);
 
-	ret=(	((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
-		((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
-		)&0xffffffffL;
 	return(ret);
 	}
 #endif
diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c
index b0779db023..920066aeba 100644
--- a/src/lib/libcrypto/x509/x509_vfy.c
+++ b/src/lib/libcrypto/x509/x509_vfy.c
@@ -694,6 +694,7 @@ static int check_cert(X509_STORE_CTX *ctx)
 	X509_CRL *crl = NULL, *dcrl = NULL;
 	X509 *x;
 	int ok, cnum;
+	unsigned int last_reasons;
 	cnum = ctx->error_depth;
 	x = sk_X509_value(ctx->chain, cnum);
 	ctx->current_cert = x;
@@ -702,6 +703,7 @@ static int check_cert(X509_STORE_CTX *ctx)
 	ctx->current_reasons = 0;
 	while (ctx->current_reasons != CRLDP_ALL_REASONS)
 		{
+		last_reasons = ctx->current_reasons;
 		/* Try to retrieve relevant CRL */
 		if (ctx->get_crl)
 			ok = ctx->get_crl(ctx, &crl, x);
@@ -745,6 +747,15 @@ static int check_cert(X509_STORE_CTX *ctx)
 		X509_CRL_free(dcrl);
 		crl = NULL;
 		dcrl = NULL;
+		/* If reasons not updated we wont get anywhere by
+		 * another iteration, so exit loop.
+		 */
+		if (last_reasons == ctx->current_reasons)
+			{
+			ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
+			ok = ctx->verify_cb(0, ctx);
+			goto err;
+			}
 		}
 	err:
 	X509_CRL_free(crl);
@@ -872,7 +883,7 @@ static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
 	{
 	ASN1_OCTET_STRING *exta, *extb;
 	int i;
-	i = X509_CRL_get_ext_by_NID(a, nid, 0);
+	i = X509_CRL_get_ext_by_NID(a, nid, -1);
 	if (i >= 0)
 		{
 		/* Can't have multiple occurrences */
@@ -883,7 +894,7 @@ static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
 	else
 		exta = NULL;
 
-	i = X509_CRL_get_ext_by_NID(b, nid, 0);
+	i = X509_CRL_get_ext_by_NID(b, nid, -1);
 
 	if (i >= 0)
 		{
@@ -1451,10 +1462,9 @@ static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
 	 * a certificate was revoked. This has since been changed since 
 	 * critical extension can change the meaning of CRL entries.
 	 */
-	if (crl->flags & EXFLAG_CRITICAL)
+	if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
+		&& (crl->flags & EXFLAG_CRITICAL))
 		{
-		if (ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
-			return 1;
 		ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
 		ok = ctx->verify_cb(0, ctx);
 		if(!ok)
diff --git a/src/lib/libcrypto/x509/x_all.c b/src/lib/libcrypto/x509/x_all.c
index b94aeeb873..e06602d65a 100644
--- a/src/lib/libcrypto/x509/x_all.c
+++ b/src/lib/libcrypto/x509/x_all.c
@@ -97,6 +97,7 @@ int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
 
 int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx)
 	{
+	x->cert_info->enc.modified = 1;
 	return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF),
 		x->cert_info->signature,
 		x->sig_alg, x->signature, x->cert_info, ctx);
@@ -123,6 +124,7 @@ int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md)
 
 int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx)
 	{
+	x->crl->enc.modified = 1;
 	return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO),
 		x->crl->sig_alg, x->sig_alg, x->signature, x->crl, ctx);
 	}
diff --git a/src/lib/libcrypto/x509v3/v3_purp.c b/src/lib/libcrypto/x509v3/v3_purp.c
index 181bd34979..ad688657e0 100644
--- a/src/lib/libcrypto/x509v3/v3_purp.c
+++ b/src/lib/libcrypto/x509v3/v3_purp.c
@@ -474,11 +474,11 @@ static void x509v3_cache_extensions(X509 *x)
 	for (i = 0; i < X509_get_ext_count(x); i++)
 		{
 		ex = X509_get_ext(x, i);
-		if (!X509_EXTENSION_get_critical(ex))
-			continue;
 		if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
 					== NID_freshest_crl)
 			x->ex_flags |= EXFLAG_FRESHEST;
+		if (!X509_EXTENSION_get_critical(ex))
+			continue;
 		if (!X509_supported_extension(ex))
 			{
 			x->ex_flags |= EXFLAG_CRITICAL;
diff --git a/src/lib/libcrypto/x86_64cpuid.pl b/src/lib/libcrypto/x86_64cpuid.pl
index 7b7b93b223..6ebfd017ea 100644
--- a/src/lib/libcrypto/x86_64cpuid.pl
+++ b/src/lib/libcrypto/x86_64cpuid.pl
@@ -11,7 +11,8 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 ($arg1,$arg2,$arg3,$arg4)=$win64?("%rcx","%rdx","%r8", "%r9") :	# Win64 order
 				 ("%rdi","%rsi","%rdx","%rcx");	# Unix order
diff --git a/src/lib/libcrypto/x86cpuid.pl b/src/lib/libcrypto/x86cpuid.pl
index 39fd8f2293..b270b44337 100644
--- a/src/lib/libcrypto/x86cpuid.pl
+++ b/src/lib/libcrypto/x86cpuid.pl
@@ -67,6 +67,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
 	&inc	("esi");		# number of cores
 
 	&mov	("eax",1);
+	&xor	("ecx","ecx");
 	&cpuid	();
 	&bt	("edx",28);
 	&jnc	(&label("generic"));
@@ -91,6 +92,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
 
 &set_label("nocacheinfo");
 	&mov	("eax",1);
+	&xor	("ecx","ecx");
 	&cpuid	();
 	&and	("edx",0xbfefffff);	# force reserved bits #20, #30 to 0
 	&cmp	("ebp",0);
@@ -165,7 +167,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
 	&jnz	(&label("nohalt"));	# not enough privileges
 
 	&pushf	();
-	&pop	("eax")
+	&pop	("eax");
 	&bt	("eax",9);
 	&jnc	(&label("nohalt"));	# interrupts are disabled
 
@@ -280,7 +282,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
 #	arguments is 1 or 2!
 &function_begin_B("OPENSSL_indirect_call");
 	{
-	my $i,$max=7;		# $max has to be chosen as 4*n-1
+	my ($max,$i)=(7,);	# $max has to be chosen as 4*n-1
 				# in order to preserve eventual
 				# stack alignment
 	&push	("ebp");
diff --git a/src/lib/libssl/d1_both.c b/src/lib/libssl/d1_both.c
index de8bab873f..2e8cf681ed 100644
--- a/src/lib/libssl/d1_both.c
+++ b/src/lib/libssl/d1_both.c
@@ -214,6 +214,12 @@ dtls1_hm_fragment_new(unsigned long frag_len, int reassembly)
 static void
 dtls1_hm_fragment_free(hm_fragment *frag)
 	{
+
+	if (frag->msg_header.is_ccs)
+		{
+		EVP_CIPHER_CTX_free(frag->msg_header.saved_retransmit_state.enc_write_ctx);
+		EVP_MD_CTX_destroy(frag->msg_header.saved_retransmit_state.write_hash);
+		}
 	if (frag->fragment) OPENSSL_free(frag->fragment);
 	if (frag->reassembly) OPENSSL_free(frag->reassembly);
 	OPENSSL_free(frag);
@@ -313,9 +319,10 @@ int dtls1_do_write(SSL *s, int type)
 				s->init_off -= DTLS1_HM_HEADER_LENGTH;
 				s->init_num += DTLS1_HM_HEADER_LENGTH;
 
-				/* write atleast DTLS1_HM_HEADER_LENGTH bytes */
-				if ( len <= DTLS1_HM_HEADER_LENGTH)  
-					len += DTLS1_HM_HEADER_LENGTH;
+				if ( s->init_num > curr_mtu)
+					len = curr_mtu;
+				else
+					len = s->init_num;
 				}
 
 			dtls1_fix_message_header(s, frag_off, 
@@ -1452,26 +1459,36 @@ dtls1_process_heartbeat(SSL *s)
 	unsigned int payload;
 	unsigned int padding = 16; /* Use minimum padding */
 
-	/* Read type and payload length first */
-	hbtype = *p++;
-	n2s(p, payload);
-	pl = p;
-
 	if (s->msg_callback)
 		s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
 			&s->s3->rrec.data[0], s->s3->rrec.length,
 			s, s->msg_callback_arg);
 
+	/* Read type and payload length first */
+	if (1 + 2 + 16 > s->s3->rrec.length)
+		return 0; /* silently discard */
+	hbtype = *p++;
+	n2s(p, payload);
+	if (1 + 2 + payload + 16 > s->s3->rrec.length)
+		return 0; /* silently discard per RFC 6520 sec. 4 */
+	pl = p;
+
 	if (hbtype == TLS1_HB_REQUEST)
 		{
 		unsigned char *buffer, *bp;
+		unsigned int write_length = 1 /* heartbeat type */ +
+					    2 /* heartbeat length */ +
+					    payload + padding;
 		int r;
 
+		if (write_length > SSL3_RT_MAX_PLAIN_LENGTH)
+			return 0;
+
 		/* Allocate memory for the response, size is 1 byte
 		 * message type, plus 2 bytes payload length, plus
 		 * payload, plus padding
 		 */
-		buffer = OPENSSL_malloc(1 + 2 + payload + padding);
+		buffer = OPENSSL_malloc(write_length);
 		bp = buffer;
 
 		/* Enter response type, length and copy payload */
@@ -1482,11 +1499,11 @@ dtls1_process_heartbeat(SSL *s)
 		/* Random padding */
 		RAND_pseudo_bytes(bp, padding);
 
-		r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
+		r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length);
 
 		if (r >= 0 && s->msg_callback)
 			s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
-				buffer, 3 + payload + padding,
+				buffer, write_length,
 				s, s->msg_callback_arg);
 
 		OPENSSL_free(buffer);
diff --git a/src/lib/libssl/d1_clnt.c b/src/lib/libssl/d1_clnt.c
index a6ed09c51d..48e5e06bde 100644
--- a/src/lib/libssl/d1_clnt.c
+++ b/src/lib/libssl/d1_clnt.c
@@ -538,13 +538,6 @@ int dtls1_connect(SSL *s)
 				SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
 			if (ret <= 0) goto end;
 
-#ifndef OPENSSL_NO_SCTP
-			/* Change to new shared key of SCTP-Auth,
-			 * will be ignored if no SCTP used.
-			 */
-			BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
-#endif
-
 			s->state=SSL3_ST_CW_FINISHED_A;
 			s->init_num=0;
 
@@ -571,6 +564,16 @@ int dtls1_connect(SSL *s)
 				goto end;
 				}
 			
+#ifndef OPENSSL_NO_SCTP
+				if (s->hit)
+					{
+					/* Change to new shared key of SCTP-Auth,
+					 * will be ignored if no SCTP used.
+					 */
+					BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
+					}
+#endif
+
 			dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
 			break;
 
@@ -613,6 +616,13 @@ int dtls1_connect(SSL *s)
 				}
 			else
 				{
+#ifndef OPENSSL_NO_SCTP
+				/* Change to new shared key of SCTP-Auth,
+				 * will be ignored if no SCTP used.
+				 */
+				BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
+#endif
+
 #ifndef OPENSSL_NO_TLSEXT
 				/* Allow NewSessionTicket if ticket expected */
 				if (s->tlsext_ticket_expected)
@@ -773,7 +783,7 @@ int dtls1_client_hello(SSL *s)
 	unsigned char *buf;
 	unsigned char *p,*d;
 	unsigned int i,j;
-	unsigned long Time,l;
+	unsigned long l;
 	SSL_COMP *comp;
 
 	buf=(unsigned char *)s->init_buf->data;
@@ -798,13 +808,11 @@ int dtls1_client_hello(SSL *s)
 
 		/* if client_random is initialized, reuse it, we are
 		 * required to use same upon reply to HelloVerify */
-		for (i=0;p[i]=='\0' && i<sizeof(s->s3->client_random);i++) ;
+		for (i=0;p[i]=='\0' && i<sizeof(s->s3->client_random);i++)
+			;
 		if (i==sizeof(s->s3->client_random))
-			{
-			Time=(unsigned long)time(NULL);	/* Time */
-			l2n(Time,p);
-			RAND_pseudo_bytes(p,sizeof(s->s3->client_random)-4);
-			}
+			ssl_fill_hello_random(s, 0, p,
+					      sizeof(s->s3->client_random));
 
 		/* Do the message type and length last */
 		d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
diff --git a/src/lib/libssl/d1_enc.c b/src/lib/libssl/d1_enc.c
index 07a5e97ce5..712c4647f2 100644
--- a/src/lib/libssl/d1_enc.c
+++ b/src/lib/libssl/d1_enc.c
@@ -126,20 +126,28 @@
 #include <openssl/des.h>
 #endif
 
+/* dtls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
+ *
+ * Returns:
+ *   0: (in non-constant time) if the record is publically invalid (i.e. too
+ *       short etc).
+ *   1: if the record's padding is valid / the encryption was successful.
+ *   -1: if the record's padding/AEAD-authenticator is invalid or, if sending,
+ *       an internal error occured. */
 int dtls1_enc(SSL *s, int send)
 	{
 	SSL3_RECORD *rec;
 	EVP_CIPHER_CTX *ds;
 	unsigned long l;
-	int bs,i,ii,j,k,n=0;
+	int bs,i,j,k,mac_size=0;
 	const EVP_CIPHER *enc;
 
 	if (send)
 		{
 		if (EVP_MD_CTX_md(s->write_hash))
 			{
-			n=EVP_MD_CTX_size(s->write_hash);
-			if (n < 0)
+			mac_size=EVP_MD_CTX_size(s->write_hash);
+			if (mac_size < 0)
 				return -1;
 			}
 		ds=s->enc_write_ctx;
@@ -164,9 +172,8 @@ int dtls1_enc(SSL *s, int send)
 		{
 		if (EVP_MD_CTX_md(s->read_hash))
 			{
-			n=EVP_MD_CTX_size(s->read_hash);
-			if (n < 0)
-				return -1;
+			mac_size=EVP_MD_CTX_size(s->read_hash);
+			OPENSSL_assert(mac_size >= 0);
 			}
 		ds=s->enc_read_ctx;
 		rec= &(s->s3->rrec);
@@ -231,7 +238,7 @@ int dtls1_enc(SSL *s, int send)
 		if (!send)
 			{
 			if (l == 0 || l%bs != 0)
-				return -1;
+				return 0;
 			}
 		
 		EVP_Cipher(ds,rec->data,rec->input,l);
@@ -246,43 +253,7 @@ int dtls1_enc(SSL *s, int send)
 #endif	/* KSSL_DEBUG */
 
 		if ((bs != 1) && !send)
-			{
-			ii=i=rec->data[l-1]; /* padding_length */
-			i++;
-			if (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG)
-				{
-				/* First packet is even in size, so check */
-				if ((memcmp(s->s3->read_sequence,
-					"\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1))
-					s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
-				if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
-					i--;
-				}
-			/* TLS 1.0 does not bound the number of padding bytes by the block size.
-			 * All of them must have value 'padding_length'. */
-			if (i + bs > (int)rec->length)
-				{
-				/* Incorrect padding. SSLerr() and ssl3_alert are done
-				 * by caller: we don't want to reveal whether this is
-				 * a decryption error or a MAC verification failure
-				 * (see http://www.openssl.org/~bodo/tls-cbc.txt) 
-				 */
-				return -1;
-				}
-			for (j=(int)(l-i); j<(int)l; j++)
-				{
-				if (rec->data[j] != ii)
-					{
-					/* Incorrect padding */
-					return -1;
-					}
-				}
-			rec->length-=i;
-
-			rec->data += bs;    /* skip the implicit IV */
-			rec->input += bs;
-			rec->length -= bs;
-			}
+			return tls1_cbc_remove_padding(s, rec, bs, mac_size);
 		}
 	return(1);
 	}
diff --git a/src/lib/libssl/d1_lib.c b/src/lib/libssl/d1_lib.c
index f61f718183..106939f241 100644
--- a/src/lib/libssl/d1_lib.c
+++ b/src/lib/libssl/d1_lib.c
@@ -196,6 +196,7 @@ void dtls1_free(SSL *s)
 	pqueue_free(s->d1->buffered_app_data.q);
 
 	OPENSSL_free(s->d1);
+	s->d1 = NULL;
 	}
 
 void dtls1_clear(SSL *s)
diff --git a/src/lib/libssl/d1_pkt.c b/src/lib/libssl/d1_pkt.c
index 987af60835..8186462d4a 100644
--- a/src/lib/libssl/d1_pkt.c
+++ b/src/lib/libssl/d1_pkt.c
@@ -376,15 +376,11 @@ static int
 dtls1_process_record(SSL *s)
 {
 	int i,al;
-	int clear=0;
 	int enc_err;
 	SSL_SESSION *sess;
 	SSL3_RECORD *rr;
-	unsigned int mac_size;
+	unsigned int mac_size, orig_len;
 	unsigned char md[EVP_MAX_MD_SIZE];
-	int decryption_failed_or_bad_record_mac = 0;
-	unsigned char *mac = NULL;
-
 
 	rr= &(s->s3->rrec);
 	sess = s->session;
@@ -416,12 +412,16 @@ dtls1_process_record(SSL *s)
 	rr->data=rr->input;
 
 	enc_err = s->method->ssl3_enc->enc(s,0);
-	if (enc_err <= 0)
+	/* enc_err is:
+	 *    0: (in non-constant time) if the record is publically invalid.
+	 *    1: if the padding is valid
+	 *    -1: if the padding is invalid */
+	if (enc_err == 0)
 		{
-		/* To minimize information leaked via timing, we will always
-		 * perform all computations before discarding the message.
-		 */
-		decryption_failed_or_bad_record_mac = 1;
+		/* For DTLS we simply ignore bad packets. */
+		rr->length = 0;
+		s->packet_length = 0;
+		goto err;
 		}
 
 #ifdef TLS_DEBUG
@@ -431,45 +431,62 @@ printf("\n");
 #endif
 
 	/* r->length is now the compressed data plus mac */
-	if (	(sess == NULL) ||
-		(s->enc_read_ctx == NULL) ||
-		(s->read_hash == NULL))
-		clear=1;
-
-	if (!clear)
+	if ((sess != NULL) &&
+	    (s->enc_read_ctx != NULL) &&
+	    (EVP_MD_CTX_md(s->read_hash) != NULL))
 		{
-		/* !clear => s->read_hash != NULL => mac_size != -1 */
-		int t;
-		t=EVP_MD_CTX_size(s->read_hash);
-		OPENSSL_assert(t >= 0);
-		mac_size=t;
-
-		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size)
+		/* s->read_hash != NULL => mac_size != -1 */
+		unsigned char *mac = NULL;
+		unsigned char mac_tmp[EVP_MAX_MD_SIZE];
+		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
+		 * amount of time if it's too short to possibly contain a MAC.
+		 */
+		if (orig_len < mac_size ||
+		    /* CBC records must have a padding length byte too. */
+		    (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+		     orig_len < mac_size+1))
 			{
-#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */
-			al=SSL_AD_RECORD_OVERFLOW;
-			SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT);
 			goto f_err;
-#else
-			decryption_failed_or_bad_record_mac = 1;
-#endif			
 			}
-		/* check the MAC for rr->input (it's in mac_size bytes at the tail) */
-		if (rr->length >= mac_size)
+
+		if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE)
 			{
+			/* We update the length so that the TLS header bytes
+			 * can be constructed correctly but we need to extract
+			 * the MAC in constant time from within the record,
+			 * without leaking the contents of the padding bytes.
+			 * */
+			mac = mac_tmp;
+			ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len);
 			rr->length -= mac_size;
-			mac = &rr->data[rr->length];
 			}
 		else
-			rr->length = 0;
-		i=s->method->ssl3_enc->mac(s,md,0);
-		if (i < 0 || mac == NULL || memcmp(md, mac, mac_size) != 0)
 			{
-			decryption_failed_or_bad_record_mac = 1;
+			/* In this case there's no padding, so |orig_len|
+			 * equals |rec->length| and we checked that there's
+			 * enough bytes for |mac_size| above. */
+			rr->length -= mac_size;
+			mac = &rr->data[rr->length];
 			}
+
+		i=s->method->ssl3_enc->mac(s,md,0 /* not send */);
+		if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0)
+			enc_err = -1;
+		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+mac_size)
+			enc_err = -1;
 		}
 
-	if (decryption_failed_or_bad_record_mac)
+	if (enc_err < 0)
 		{
 		/* decryption failed, silently discard message */
 		rr->length = 0;
@@ -830,6 +847,12 @@ start:
 			}
 		}
 
+	if (s->d1->listen && rr->type != SSL3_RT_HANDSHAKE)
+		{
+		rr->length = 0;
+		goto start;
+		}
+
 	/* we now have a packet which can be read and processed */
 
 	if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
@@ -1034,6 +1057,7 @@ start:
 			!(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
 			!s->s3->renegotiate)
 			{
+			s->d1->handshake_read_seq++;
 			s->new_session = 1;
 			ssl3_renegotiate(s);
 			if (ssl3_renegotiate_check(s))
diff --git a/src/lib/libssl/d1_srtp.c b/src/lib/libssl/d1_srtp.c
index 928935bd8b..ab9c41922c 100644
--- a/src/lib/libssl/d1_srtp.c
+++ b/src/lib/libssl/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/src/lib/libssl/d1_srvr.c b/src/lib/libssl/d1_srvr.c
index 29421da9aa..9975e20873 100644
--- a/src/lib/libssl/d1_srvr.c
+++ b/src/lib/libssl/d1_srvr.c
@@ -276,10 +276,11 @@ int dtls1_accept(SSL *s)
 		case SSL3_ST_SW_HELLO_REQ_B:
 
 			s->shutdown=0;
+			dtls1_clear_record_buffer(s);
 			dtls1_start_timer(s);
 			ret=dtls1_send_hello_request(s);
 			if (ret <= 0) goto end;
-			s->s3->tmp.next_state=SSL3_ST_SW_HELLO_REQ_C;
+			s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A;
 			s->state=SSL3_ST_SW_FLUSH;
 			s->init_num=0;
 
@@ -721,10 +722,13 @@ int dtls1_accept(SSL *s)
 			if (ret <= 0) goto end;
 
 #ifndef OPENSSL_NO_SCTP
-			/* Change to new shared key of SCTP-Auth,
-			 * will be ignored if no SCTP used.
-			 */
-			BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
+			if (!s->hit)
+				{
+				/* Change to new shared key of SCTP-Auth,
+				 * will be ignored if no SCTP used.
+				 */
+				BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
+				}
 #endif
 
 			s->state=SSL3_ST_SW_FINISHED_A;
@@ -749,7 +753,16 @@ int dtls1_accept(SSL *s)
 			if (ret <= 0) goto end;
 			s->state=SSL3_ST_SW_FLUSH;
 			if (s->hit)
+				{
 				s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
+
+#ifndef OPENSSL_NO_SCTP
+				/* Change to new shared key of SCTP-Auth,
+				 * will be ignored if no SCTP used.
+				 */
+				BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, 0, NULL);
+#endif
+				}
 			else
 				{
 				s->s3->tmp.next_state=SSL_ST_OK;
@@ -912,15 +925,13 @@ int dtls1_send_server_hello(SSL *s)
 	unsigned char *p,*d;
 	int i;
 	unsigned int sl;
-	unsigned long l,Time;
+	unsigned long l;
 
 	if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
 		{
 		buf=(unsigned char *)s->init_buf->data;
 		p=s->s3->server_random;
-		Time=(unsigned long)time(NULL);			/* Time */
-		l2n(Time,p);
-		RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4);
+		ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE);
 		/* Do the message type and length last */
 		d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
 
diff --git a/src/lib/libssl/dtls1.h b/src/lib/libssl/dtls1.h
index 5008bf6081..e65d501191 100644
--- a/src/lib/libssl/dtls1.h
+++ b/src/lib/libssl/dtls1.h
@@ -57,8 +57,8 @@
  *
  */
 
-#ifndef HEADER_DTLS1_H 
-#define HEADER_DTLS1_H 
+#ifndef HEADER_DTLS1_H
+#define HEADER_DTLS1_H
 
 #include <openssl/buffer.h>
 #include <openssl/pqueue.h>
@@ -72,8 +72,12 @@
 #elif defined(OPENSSL_SYS_NETWARE) && !defined(_WINSOCK2API_)
 #include <sys/timeval.h>
 #else
+#if defined(OPENSSL_SYS_VXWORKS)
+#include <sys/times.h>
+#else
 #include <sys/time.h>
 #endif
+#endif
 
 #ifdef  __cplusplus
 extern "C" {
diff --git a/src/lib/libssl/s23_clnt.c b/src/lib/libssl/s23_clnt.c
index 47673e740a..2b93c639dd 100644
--- a/src/lib/libssl/s23_clnt.c
+++ b/src/lib/libssl/s23_clnt.c
@@ -269,12 +269,35 @@ static int ssl23_no_ssl2_ciphers(SSL *s)
 	return 1;
 	}
 
+/* Fill a ClientRandom or ServerRandom field of length len. Returns <= 0
+ * on failure, 1 on success. */
+int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, int len)
+	{
+	int send_time = 0;
+
+	if (len < 4)
+		return 0;
+	if (server)
+		send_time = (s->mode & SSL_MODE_SEND_SERVERHELLO_TIME) != 0;
+	else
+		send_time = (s->mode & SSL_MODE_SEND_CLIENTHELLO_TIME) != 0;
+	if (send_time)
+		{
+		unsigned long Time = (unsigned long)time(NULL);
+		unsigned char *p = result;
+		l2n(Time, p);
+		return RAND_pseudo_bytes(p, len-4);
+		}
+	else
+		return RAND_pseudo_bytes(result, len);
+	}
+
 static int ssl23_client_hello(SSL *s)
 	{
 	unsigned char *buf;
 	unsigned char *p,*d;
 	int i,ch_len;
-	unsigned long Time,l;
+	unsigned long l;
 	int ssl2_compat;
 	int version = 0, version_major, version_minor;
 #ifndef OPENSSL_NO_COMP
@@ -355,9 +378,7 @@ static int ssl23_client_hello(SSL *s)
 #endif
 
 		p=s->s3->client_random;
-		Time=(unsigned long)time(NULL);		/* Time */
-		l2n(Time,p);
-		if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
+		if (ssl_fill_hello_random(s, 0, p, SSL3_RANDOM_SIZE) <= 0)
 			return -1;
 
 		if (version == TLS1_2_VERSION)
diff --git a/src/lib/libssl/s3_both.c b/src/lib/libssl/s3_both.c
index b63460a56d..53b9390fdd 100644
--- a/src/lib/libssl/s3_both.c
+++ b/src/lib/libssl/s3_both.c
@@ -161,6 +161,8 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
 
 		i=s->method->ssl3_enc->final_finish_mac(s,
 			sender,slen,s->s3->tmp.finish_md);
+		if (i == 0)
+			return 0;
 		s->s3->tmp.finish_md_len = i;
 		memcpy(p, s->s3->tmp.finish_md, i);
 		p+=i;
@@ -204,10 +206,15 @@ int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
 
 #ifndef OPENSSL_NO_NEXTPROTONEG
 /* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen to far. */
-static void ssl3_take_mac(SSL *s) {
+static void ssl3_take_mac(SSL *s)
+	{
 	const char *sender;
 	int slen;
-
+	/* If no new cipher setup return immediately: other functions will
+	 * set the appropriate error.
+	 */
+	if (s->s3->tmp.new_cipher == NULL)
+		return;
 	if (s->state & SSL_ST_CONNECT)
 		{
 		sender=s->method->ssl3_enc->server_finished_label;
@@ -221,7 +228,7 @@ static void ssl3_take_mac(SSL *s) {
 
 	s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
 		sender,slen,s->s3->tmp.peer_finish_md);
-}
+	}
 #endif
 
 int ssl3_get_finished(SSL *s, int a, int b)
@@ -231,8 +238,9 @@ int ssl3_get_finished(SSL *s, int a, int b)
 	unsigned char *p;
 
 #ifdef OPENSSL_NO_NEXTPROTONEG
-	/* the mac has already been generated when we received the change
-	 * cipher spec message and is in s->s3->tmp.peer_finish_md. */
+	/* the mac has already been generated when we received the
+	 * change cipher spec message and is in s->s3->tmp.peer_finish_md.
+	 */ 
 #endif
 
 	n=s->method->ssl_get_message(s,
@@ -263,7 +271,7 @@ int ssl3_get_finished(SSL *s, int a, int b)
 		goto f_err;
 		}
 
-	if (memcmp(p, s->s3->tmp.peer_finish_md, i) != 0)
+	if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0)
 		{
 		al=SSL_AD_DECRYPT_ERROR;
 		SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_DIGEST_CHECK_FAILED);
@@ -537,12 +545,14 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
 		s->init_num += i;
 		n -= i;
 		}
+
 #ifndef OPENSSL_NO_NEXTPROTONEG
 	/* If receiving Finished, record MAC of prior handshake messages for
 	 * Finished verification. */
 	if (*s->init_buf->data == SSL3_MT_FINISHED)
 		ssl3_take_mac(s);
 #endif
+
 	/* Feed this message into MAC computation. */
 	ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
 	if (s->msg_callback)
diff --git a/src/lib/libssl/s3_clnt.c b/src/lib/libssl/s3_clnt.c
index b80d052e1f..a6b3c01afa 100644
--- a/src/lib/libssl/s3_clnt.c
+++ b/src/lib/libssl/s3_clnt.c
@@ -459,7 +459,6 @@ int ssl3_connect(SSL *s)
 				SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
 			if (ret <= 0) goto end;
 
-
 #if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
 			s->state=SSL3_ST_CW_FINISHED_A;
 #else
@@ -656,7 +655,7 @@ int ssl3_client_hello(SSL *s)
 	unsigned char *buf;
 	unsigned char *p,*d;
 	int i;
-	unsigned long Time,l;
+	unsigned long l;
 #ifndef OPENSSL_NO_COMP
 	int j;
 	SSL_COMP *comp;
@@ -681,9 +680,8 @@ int ssl3_client_hello(SSL *s)
 		/* else use the pre-loaded session */
 
 		p=s->s3->client_random;
-		Time=(unsigned long)time(NULL);			/* Time */
-		l2n(Time,p);
-		if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
+
+		if (ssl_fill_hello_random(s, 0, p, SSL3_RANDOM_SIZE) <= 0)
 			goto err;
 
 		/* Do the message type and length last */
@@ -987,7 +985,10 @@ int ssl3_get_server_hello(SSL *s)
 	 * 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/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c
index fb60cde8ee..c4ef2738d7 100644
--- a/src/lib/libssl/s3_lib.c
+++ b/src/lib/libssl/s3_lib.c
@@ -1125,7 +1125,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
 	0, /* not implemented (non-ephemeral DH) */
 	TLS1_TXT_DH_DSS_WITH_AES_128_SHA256,
 	TLS1_CK_DH_DSS_WITH_AES_128_SHA256,
-	SSL_kDHr,
+	SSL_kDHd,
 	SSL_aDH,
 	SSL_AES128,
 	SSL_SHA256,
@@ -1407,7 +1407,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
 	0, /* not implemented (non-ephemeral DH) */
 	TLS1_TXT_DH_DSS_WITH_AES_256_SHA256,
 	TLS1_CK_DH_DSS_WITH_AES_256_SHA256,
-	SSL_kDHr,
+	SSL_kDHd,
 	SSL_aDH,
 	SSL_AES256,
 	SSL_SHA256,
@@ -1683,7 +1683,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
 	SSL_3DES,
 	SSL_SHA1,
 	SSL_TLSV1,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	168,
 	168,
@@ -1699,7 +1699,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
 	SSL_AES128,
 	SSL_SHA1,
 	SSL_TLSV1,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	128,
 	128,
@@ -1715,7 +1715,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
 	SSL_AES256,
 	SSL_SHA1,
 	SSL_TLSV1,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
 	256,
 	256,
@@ -1958,7 +1958,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
 	0,
 	TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256,
 	TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256,
-	SSL_kDHr,
+	SSL_kDHd,
 	SSL_aDH,
 	SSL_AES128GCM,
 	SSL_AEAD,
@@ -1974,7 +1974,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
 	0,
 	TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384,
 	TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384,
-	SSL_kDHr,
+	SSL_kDHd,
 	SSL_aDH,
 	SSL_AES256GCM,
 	SSL_AEAD,
@@ -2669,7 +2669,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
 	1,
 	TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256,
 	TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256,
-	SSL_kECDHe,
+	SSL_kECDHr,
 	SSL_aECDH,
 	SSL_AES128,
 	SSL_SHA256,
@@ -2685,7 +2685,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
 	1,
 	TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384,
 	TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384,
-	SSL_kECDHe,
+	SSL_kECDHr,
 	SSL_aECDH,
 	SSL_AES256,
 	SSL_SHA384,
@@ -2799,7 +2799,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
 	1,
 	TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256,
 	TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256,
-	SSL_kECDHe,
+	SSL_kECDHr,
 	SSL_aECDH,
 	SSL_AES128GCM,
 	SSL_AEAD,
@@ -2815,7 +2815,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={
 	1,
 	TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384,
 	TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384,
-	SSL_kECDHe,
+	SSL_kECDHr,
 	SSL_aECDH,
 	SSL_AES256GCM,
 	SSL_AEAD,
@@ -3037,6 +3037,11 @@ void ssl3_clear(SSL *s)
 		s->s3->tmp.ecdh = NULL;
 		}
 #endif
+#ifndef OPENSSL_NO_TLSEXT
+#ifndef OPENSSL_NO_EC
+	s->s3->is_probably_safari = 0;
+#endif /* !OPENSSL_NO_EC */
+#endif /* !OPENSSL_NO_TLSEXT */
 
 	rp = s->s3->rbuf.buf;
 	wp = s->s3->wbuf.buf;
@@ -4016,6 +4021,13 @@ SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
 		ii=sk_SSL_CIPHER_find(allow,c);
 		if (ii >= 0)
 			{
+#if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_TLSEXT)
+			if ((alg_k & SSL_kEECDH) && (alg_a & SSL_aECDSA) && s->s3->is_probably_safari)
+				{
+				if (!ret) ret=sk_SSL_CIPHER_value(allow,ii);
+				continue;
+				}
+#endif
 			ret=sk_SSL_CIPHER_value(allow,ii);
 			break;
 			}
@@ -4274,7 +4286,7 @@ need to go to SSL_ST_ACCEPT.
 long ssl_get_algorithm2(SSL *s)
 	{
 	long alg2 = s->s3->tmp.new_cipher->algorithm2;
-	if (TLS1_get_version(s) >= TLS1_2_VERSION &&
+	if (s->method->version == TLS1_2_VERSION &&
 	    alg2 == (SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF))
 		return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
 	return alg2;
diff --git a/src/lib/libssl/s3_pkt.c b/src/lib/libssl/s3_pkt.c
index adf8c387cc..96ba63262e 100644
--- a/src/lib/libssl/s3_pkt.c
+++ b/src/lib/libssl/s3_pkt.c
@@ -290,11 +290,8 @@ static int ssl3_get_record(SSL *s)
 	unsigned char *p;
 	unsigned char md[EVP_MAX_MD_SIZE];
 	short version;
-	int mac_size;
-	int clear=0;
+	unsigned mac_size, orig_len;
 	size_t extra;
-	int decryption_failed_or_bad_record_mac = 0;
-	unsigned char *mac = NULL;
 
 	rr= &(s->s3->rrec);
 	sess=s->session;
@@ -338,7 +335,7 @@ fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length);
 			if (version != s->version)
 				{
 				SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
-                                if ((s->version & 0xFF00) == (version & 0xFF00))
+                                if ((s->version & 0xFF00) == (version & 0xFF00) && !s->enc_write_ctx && !s->write_hash)
                                 	/* Send back error using their minor version number :-) */
 					s->version = (unsigned short)version;
 				al=SSL_AD_PROTOCOL_VERSION;
@@ -403,17 +400,15 @@ fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length);
 	rr->data=rr->input;
 
 	enc_err = s->method->ssl3_enc->enc(s,0);
-	if (enc_err <= 0)
+	/* enc_err is:
+	 *    0: (in non-constant time) if the record is publically invalid.
+	 *    1: if the padding is valid
+	 *    -1: if the padding is invalid */
+	if (enc_err == 0)
 		{
-		if (enc_err == 0)
-			/* SSLerr() and ssl3_send_alert() have been called */
-			goto err;
-
-		/* Otherwise enc_err == -1, which indicates bad padding
-		 * (rec->length has not been changed in this case).
-		 * To minimize information leaked via timing, we will perform
-		 * the MAC computation anyway. */
-		decryption_failed_or_bad_record_mac = 1;
+		al=SSL_AD_DECRYPTION_FAILED;
+		SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
+		goto f_err;
 		}
 
 #ifdef TLS_DEBUG
@@ -423,53 +418,62 @@ printf("\n");
 #endif
 
 	/* r->length is now the compressed data plus mac */
-	if (	(sess == NULL) ||
-		(s->enc_read_ctx == NULL) ||
-		(EVP_MD_CTX_md(s->read_hash) == NULL))
-		clear=1;
-
-	if (!clear)
+	if ((sess != NULL) &&
+	    (s->enc_read_ctx != NULL) &&
+	    (EVP_MD_CTX_md(s->read_hash) != NULL))
 		{
-		/* !clear => s->read_hash != NULL => mac_size != -1 */
+		/* s->read_hash != NULL => mac_size != -1 */
+		unsigned char *mac = NULL;
+		unsigned char mac_tmp[EVP_MAX_MD_SIZE];
 		mac_size=EVP_MD_CTX_size(s->read_hash);
-		OPENSSL_assert(mac_size >= 0);
+		OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
 
-		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_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
+		 * amount of time if it's too short to possibly contain a MAC.
+		 */
+		if (orig_len < mac_size ||
+		    /* CBC records must have a padding length byte too. */
+		    (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+		     orig_len < mac_size+1))
 			{
-#if 0 /* OK only for stream ciphers (then rr->length is visible from ciphertext anyway) */
-			al=SSL_AD_RECORD_OVERFLOW;
-			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG);
+			al=SSL_AD_DECODE_ERROR;
+			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT);
 			goto f_err;
-#else
-			decryption_failed_or_bad_record_mac = 1;
-#endif			
 			}
-		/* check the MAC for rr->input (it's in mac_size bytes at the tail) */
-		if (rr->length >= (unsigned int)mac_size)
+
+		if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE)
 			{
+			/* We update the length so that the TLS header bytes
+			 * can be constructed correctly but we need to extract
+			 * the MAC in constant time from within the record,
+			 * without leaking the contents of the padding bytes.
+			 * */
+			mac = mac_tmp;
+			ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len);
 			rr->length -= mac_size;
-			mac = &rr->data[rr->length];
 			}
 		else
 			{
-			/* record (minus padding) is too short to contain a MAC */
-#if 0 /* OK only for stream ciphers */
-			al=SSL_AD_DECODE_ERROR;
-			SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_LENGTH_TOO_SHORT);
-			goto f_err;
-#else
-			decryption_failed_or_bad_record_mac = 1;
-			rr->length = 0;
-#endif
-			}
-		i=s->method->ssl3_enc->mac(s,md,0);
-		if (i < 0 || mac == NULL || memcmp(md, mac, (size_t)mac_size) != 0)
-			{
-			decryption_failed_or_bad_record_mac = 1;
+			/* In this case there's no padding, so |orig_len|
+			 * equals |rec->length| and we checked that there's
+			 * enough bytes for |mac_size| above. */
+			rr->length -= mac_size;
+			mac = &rr->data[rr->length];
 			}
+
+		i=s->method->ssl3_enc->mac(s,md,0 /* not send */);
+		if (i < 0 || mac == NULL || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0)
+			enc_err = -1;
+		if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH+extra+mac_size)
+			enc_err = -1;
 		}
 
-	if (decryption_failed_or_bad_record_mac)
+	if (enc_err < 0)
 		{
 		/* A separate 'decryption_failed' alert was introduced with TLS 1.0,
 		 * SSL 3.0 only has 'bad_record_mac'.  But unless a decryption
@@ -744,6 +748,7 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
 	 * bytes and record version number > TLS 1.0
 	 */
 	if (s->state == SSL3_ST_CW_CLNT_HELLO_B
+				&& !s->renegotiate
 				&& TLS1_get_version(s) > TLS1_VERSION)
 		*(p++) = 0x1;
 	else
@@ -1238,7 +1243,7 @@ start:
 				goto f_err;
 				}
 #ifdef SSL_AD_MISSING_SRP_USERNAME
-			if (alert_descr == SSL_AD_MISSING_SRP_USERNAME)
+			else if (alert_descr == SSL_AD_MISSING_SRP_USERNAME)
 				return(0);
 #endif
 			}
@@ -1454,8 +1459,14 @@ int ssl3_do_change_cipher_spec(SSL *s)
 		slen=s->method->ssl3_enc->client_finished_label_len;
 		}
 
-	s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
+	i = s->method->ssl3_enc->final_finish_mac(s,
 		sender,slen,s->s3->tmp.peer_finish_md);
+	if (i == 0)
+		{
+		SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR);
+		return 0;
+		}
+	s->s3->tmp.peer_finish_md_len = i;
 
 	return(1);
 	}
diff --git a/src/lib/libssl/s3_srvr.c b/src/lib/libssl/s3_srvr.c
index 118939fabb..9ac19c05f2 100644
--- a/src/lib/libssl/s3_srvr.c
+++ b/src/lib/libssl/s3_srvr.c
@@ -191,7 +191,8 @@ static int ssl_check_srp_ext_ClientHello(SSL *s, int *al)
 		{
 		if(s->srp_ctx.login == NULL)
 			{
-			/* There isn't any srp login extension !!! */
+			/* RFC 5054 says SHOULD reject, 
+			   we do so if There is no srp login name */
 			ret = SSL3_AL_FATAL;
 			*al = SSL_AD_UNKNOWN_PSK_IDENTITY;
 			}
@@ -378,6 +379,7 @@ int ssl3_accept(SSL *s)
 				}
 			}
 #endif		
+			
 			s->renegotiate = 2;
 			s->state=SSL3_ST_SW_SRVR_HELLO_A;
 			s->init_num=0;
@@ -956,7 +958,8 @@ int ssl3_get_client_hello(SSL *s)
 	    (s->version != DTLS1_VERSION && s->client_version < s->version))
 		{
 		SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER);
-		if ((s->client_version>>8) == SSL3_VERSION_MAJOR)
+		if ((s->client_version>>8) == SSL3_VERSION_MAJOR && 
+			!s->enc_write_ctx && !s->write_hash)
 			{
 			/* similar to ssl3_get_record, send alert using remote version number */
 			s->version = s->client_version;
@@ -1181,7 +1184,7 @@ int ssl3_get_client_hello(SSL *s)
 			goto f_err;
 			}
 		}
-		if (ssl_check_clienthello_tlsext(s) <= 0) {
+		if (ssl_check_clienthello_tlsext_early(s) <= 0) {
 			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
 			goto err;
 		}
@@ -1191,12 +1194,9 @@ int ssl3_get_client_hello(SSL *s)
 	 * server_random before calling tls_session_secret_cb in order to allow
 	 * SessionTicket processing to use it in key derivation. */
 	{
-		unsigned long Time;
 		unsigned char *pos;
-		Time=(unsigned long)time(NULL);			/* Time */
 		pos=s->s3->server_random;
-		l2n(Time,pos);
-		if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0)
+		if (ssl_fill_hello_random(s, 1, pos, SSL3_RANDOM_SIZE) <= 0)
 			{
 			al=SSL_AD_INTERNAL_ERROR;
 			goto f_err;
@@ -1389,7 +1389,10 @@ int ssl3_get_client_hello(SSL *s)
 	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. 
@@ -1403,6 +1406,16 @@ int ssl3_get_client_hello(SSL *s)
 	 * s->tmp.new_cipher	- the new cipher to use.
 	 */
 
+	/* Handles TLS extensions that we couldn't check earlier */
+	if (s->version >= SSL3_VERSION)
+		{
+		if (ssl_check_clienthello_tlsext_late(s) <= 0)
+			{
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
+			goto err;
+			}
+		}
+
 	if (ret < 0) ret=1;
 	if (0)
 		{
@@ -1420,19 +1433,13 @@ int ssl3_send_server_hello(SSL *s)
 	unsigned char *p,*d;
 	int i,sl;
 	unsigned long l;
-#ifdef OPENSSL_NO_TLSEXT
-	unsigned long Time;
-#endif
 
 	if (s->state == SSL3_ST_SW_SRVR_HELLO_A)
 		{
 		buf=(unsigned char *)s->init_buf->data;
 #ifdef OPENSSL_NO_TLSEXT
 		p=s->s3->server_random;
-		/* Generate server_random if it was not needed previously */
-		Time=(unsigned long)time(NULL);			/* Time */
-		l2n(Time,p);
-		if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0)
+		if (ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE) <= 0)
 			return -1;
 #endif
 		/* Do the message type and length last */
@@ -1823,7 +1830,7 @@ int ssl3_send_server_key_exchange(SSL *s)
 			SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
 			goto f_err;
 			}
-		for (i=0; r[i] != NULL && i<4; i++)
+		for (i=0; i < 4 && r[i] != NULL; i++)
 			{
 			nr[i]=BN_num_bytes(r[i]);
 #ifndef OPENSSL_NO_SRP
@@ -1859,7 +1866,7 @@ int ssl3_send_server_key_exchange(SSL *s)
 		d=(unsigned char *)s->init_buf->data;
 		p= &(d[4]);
 
-		for (i=0; r[i] != NULL && i<4; i++)
+		for (i=0; i < 4 && r[i] != NULL; i++)
 			{
 #ifndef OPENSSL_NO_SRP
 			if ((i == 2) && (type & SSL_kSRP))
diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h
index 8b0c2a2dac..7219a0e64b 100644
--- a/src/lib/libssl/ssl.h
+++ b/src/lib/libssl/ssl.h
@@ -493,6 +493,9 @@ struct ssl_session_st
 	char *psk_identity_hint;
 	char *psk_identity;
 #endif
+	/* Used to indicate that session resumption is not allowed.
+	 * Applications can also set this bit for a new session via
+	 * not_resumable_session_cb to disable session caching and tickets. */
 	int not_resumable;
 
 	/* The cert is the certificate used to establish this connection */
@@ -535,7 +538,7 @@ struct ssl_session_st
 #endif /* OPENSSL_NO_EC */
 	/* RFC4507 info */
 	unsigned char *tlsext_tick;	/* Session ticket */
-	size_t	tlsext_ticklen;		/* Session ticket length */	
+	size_t tlsext_ticklen;		/* Session ticket length */
 	long tlsext_tick_lifetime_hint;	/* Session lifetime hint in seconds */
 #endif
 #ifndef OPENSSL_NO_SRP
@@ -552,11 +555,14 @@ struct ssl_session_st
 #define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG		0x00000008L
 #define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG		0x00000010L
 #define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER		0x00000020L
-#define SSL_OP_MSIE_SSLV2_RSA_PADDING			0x00000040L /* no effect since 0.9.7h and 0.9.8b */
+#define SSL_OP_SAFARI_ECDHE_ECDSA_BUG			0x00000040L
 #define SSL_OP_SSLEAY_080_CLIENT_DH_BUG			0x00000080L
 #define SSL_OP_TLS_D5_BUG				0x00000100L
 #define SSL_OP_TLS_BLOCK_PADDING_BUG			0x00000200L
 
+/* Hasn't done anything since OpenSSL 0.9.7h, retained for compatibility */
+#define SSL_OP_MSIE_SSLV2_RSA_PADDING			0x0
+
 /* Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added
  * in OpenSSL 0.9.6d.  Usually (depending on the application protocol)
  * the workaround is not needed.  Unfortunately some broken SSL/TLS
@@ -638,6 +644,12 @@ struct ssl_session_st
  * TLS only.)  "Released" buffers are put onto a free-list in the context
  * or just freed (depending on the context's setting for freelist_max_len). */
 #define SSL_MODE_RELEASE_BUFFERS 0x00000010L
+/* Send the current time in the Random fields of the ClientHello and
+ * ServerHello records for compatibility with hypothetical implementations
+ * that require it.
+ */
+#define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L
+#define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L
 
 /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
  * they cannot be used to clear bits. */
@@ -903,7 +915,7 @@ struct ssl_ctx_st
 	 */
 	unsigned int max_send_fragment;
 
-#ifndef OPENSSL_ENGINE
+#ifndef OPENSSL_NO_ENGINE
 	/* Engine to pass requests for client certs to
 	 */
 	ENGINE *client_cert_engine;
@@ -927,6 +939,7 @@ struct ssl_ctx_st
 	/* Callback for status request */
 	int (*tlsext_status_cb)(SSL *ssl, void *arg);
 	void *tlsext_status_arg;
+
 	/* draft-rescorla-tls-opaque-prf-input-00.txt information */
 	int (*tlsext_opaque_prf_input_callback)(SSL *, void *peerinput, size_t len, void *arg);
 	void *tlsext_opaque_prf_input_callback_arg;
@@ -952,6 +965,7 @@ struct ssl_ctx_st
 #endif
 
 #ifndef OPENSSL_NO_TLSEXT
+
 # ifndef OPENSSL_NO_NEXTPROTONEG
 	/* Next protocol negotiation information */
 	/* (for experimental NPN extension). */
@@ -2206,6 +2220,7 @@ void ERR_load_SSL_strings(void);
 #define SSL_F_SSL_GET_NEW_SESSION			 181
 #define SSL_F_SSL_GET_PREV_SESSION			 217
 #define SSL_F_SSL_GET_SERVER_SEND_CERT			 182
+#define SSL_F_SSL_GET_SERVER_SEND_PKEY			 317
 #define SSL_F_SSL_GET_SIGN_PKEY				 183
 #define SSL_F_SSL_INIT_WBIO_BUFFER			 184
 #define SSL_F_SSL_LOAD_CLIENT_CA_FILE			 185
diff --git a/src/lib/libssl/ssl3.h b/src/lib/libssl/ssl3.h
index 112e627de0..cb8b2492ec 100644
--- a/src/lib/libssl/ssl3.h
+++ b/src/lib/libssl/ssl3.h
@@ -539,6 +539,15 @@ typedef struct ssl3_state_st
 	/* Set if we saw the Next Protocol Negotiation extension from our peer. */
 	int next_proto_neg_seen;
 #endif
+
+#ifndef OPENSSL_NO_TLSEXT
+#ifndef OPENSSL_NO_EC
+	/* This is set to true if we believe that this is a version of Safari
+	 * running on OS X 10.6 or newer. We wish to know this because Safari
+	 * on 10.8 .. 10.8.3 has broken ECDHE-ECDSA support. */
+	char is_probably_safari;
+#endif /* !OPENSSL_NO_EC */
+#endif /* !OPENSSL_NO_TLSEXT */
 	} SSL3_STATE;
 
 #endif
@@ -578,8 +587,10 @@ typedef struct ssl3_state_st
 #define SSL3_ST_CW_CERT_VRFY_B		(0x191|SSL_ST_CONNECT)
 #define SSL3_ST_CW_CHANGE_A		(0x1A0|SSL_ST_CONNECT)
 #define SSL3_ST_CW_CHANGE_B		(0x1A1|SSL_ST_CONNECT)
+#ifndef OPENSSL_NO_NEXTPROTONEG
 #define SSL3_ST_CW_NEXT_PROTO_A		(0x200|SSL_ST_CONNECT)
 #define SSL3_ST_CW_NEXT_PROTO_B		(0x201|SSL_ST_CONNECT)
+#endif
 #define SSL3_ST_CW_FINISHED_A		(0x1B0|SSL_ST_CONNECT)
 #define SSL3_ST_CW_FINISHED_B		(0x1B1|SSL_ST_CONNECT)
 /* read from server */
@@ -629,8 +640,10 @@ typedef struct ssl3_state_st
 #define SSL3_ST_SR_CERT_VRFY_B		(0x1A1|SSL_ST_ACCEPT)
 #define SSL3_ST_SR_CHANGE_A		(0x1B0|SSL_ST_ACCEPT)
 #define SSL3_ST_SR_CHANGE_B		(0x1B1|SSL_ST_ACCEPT)
+#ifndef OPENSSL_NO_NEXTPROTONEG
 #define SSL3_ST_SR_NEXT_PROTO_A		(0x210|SSL_ST_ACCEPT)
 #define SSL3_ST_SR_NEXT_PROTO_B		(0x211|SSL_ST_ACCEPT)
+#endif
 #define SSL3_ST_SR_FINISHED_A		(0x1C0|SSL_ST_ACCEPT)
 #define SSL3_ST_SR_FINISHED_B		(0x1C1|SSL_ST_ACCEPT)
 /* write to client */
@@ -655,7 +668,9 @@ typedef struct ssl3_state_st
 #define SSL3_MT_CLIENT_KEY_EXCHANGE		16
 #define SSL3_MT_FINISHED			20
 #define SSL3_MT_CERTIFICATE_STATUS		22
+#ifndef OPENSSL_NO_NEXTPROTONEG
 #define SSL3_MT_NEXT_PROTO			67
+#endif
 #define DTLS1_MT_HELLO_VERIFY_REQUEST    3
 
 
diff --git a/src/lib/libssl/ssl_algs.c b/src/lib/libssl/ssl_algs.c
index d443143c59..9c34d19725 100644
--- a/src/lib/libssl/ssl_algs.c
+++ b/src/lib/libssl/ssl_algs.c
@@ -94,6 +94,7 @@ int SSL_library_init(void)
 	EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1());
 	EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
 #endif
+
 #endif
 #ifndef OPENSSL_NO_CAMELLIA
 	EVP_add_cipher(EVP_camellia_128_cbc());
diff --git a/src/lib/libssl/ssl_cert.c b/src/lib/libssl/ssl_cert.c
index 917be31876..5123a89182 100644
--- a/src/lib/libssl/ssl_cert.c
+++ b/src/lib/libssl/ssl_cert.c
@@ -164,14 +164,14 @@ static void ssl_cert_set_default_md(CERT *cert)
 	{
 	/* Set digest values to defaults */
 #ifndef OPENSSL_NO_DSA
-	cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_dss1();
+	cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
 #endif
 #ifndef OPENSSL_NO_RSA
 	cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
 	cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
 #endif
 #ifndef OPENSSL_NO_ECDSA
-	cert->pkeys[SSL_PKEY_ECC].digest = EVP_ecdsa();
+	cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
 #endif
 	}
 
diff --git a/src/lib/libssl/ssl_ciph.c b/src/lib/libssl/ssl_ciph.c
index 92d1e94d6a..0aba8e048c 100644
--- a/src/lib/libssl/ssl_ciph.c
+++ b/src/lib/libssl/ssl_ciph.c
@@ -312,6 +312,7 @@ static const SSL_CIPHER cipher_aliases[]={
 	{0,SSL_TXT_SSLV2,0,   0,0,0,0,SSL_SSLV2, 0,0,0,0},
 	{0,SSL_TXT_SSLV3,0,   0,0,0,0,SSL_SSLV3, 0,0,0,0},
 	{0,SSL_TXT_TLSV1,0,   0,0,0,0,SSL_TLSV1, 0,0,0,0},
+	{0,SSL_TXT_TLSV1_2,0, 0,0,0,0,SSL_TLSV1_2, 0,0,0,0},
 
 	/* export flag */
 	{0,SSL_TXT_EXP,0,     0,0,0,0,0,SSL_EXPORT,0,0,0},
@@ -1150,9 +1151,9 @@ static int ssl_cipher_process_rulestr(const char *rule_str,
 			while (	((ch >= 'A') && (ch <= 'Z')) ||
 				((ch >= '0') && (ch <= '9')) ||
 				((ch >= 'a') && (ch <= 'z')) ||
-				 (ch == '-'))
+				 (ch == '-') || (ch == '.'))
 #else
-			while (	isalnum(ch) || (ch == '-'))
+			while (	isalnum(ch) || (ch == '-') || (ch == '.'))
 #endif
 				 {
 				 ch = *(++l);
diff --git a/src/lib/libssl/ssl_err.c b/src/lib/libssl/ssl_err.c
index 2577c6895a..370fb57e3b 100644
--- a/src/lib/libssl/ssl_err.c
+++ b/src/lib/libssl/ssl_err.c
@@ -228,6 +228,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
 {ERR_FUNC(SSL_F_SSL_GET_NEW_SESSION),	"SSL_GET_NEW_SESSION"},
 {ERR_FUNC(SSL_F_SSL_GET_PREV_SESSION),	"SSL_GET_PREV_SESSION"},
 {ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_CERT),	"SSL_GET_SERVER_SEND_CERT"},
+{ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_PKEY),	"SSL_GET_SERVER_SEND_PKEY"},
 {ERR_FUNC(SSL_F_SSL_GET_SIGN_PKEY),	"SSL_GET_SIGN_PKEY"},
 {ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER),	"SSL_INIT_WBIO_BUFFER"},
 {ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE),	"SSL_load_client_CA_file"},
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c
index f82d071d6e..6dbc3c1f7d 100644
--- a/src/lib/libssl/ssl_lib.c
+++ b/src/lib/libssl/ssl_lib.c
@@ -597,8 +597,10 @@ void SSL_free(SSL *s)
 		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);
 	}
@@ -1795,7 +1797,9 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
 	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data);
 
 	ret->extra_certs=NULL;
-	ret->comp_methods=SSL_COMP_get_compression_methods();
+	/* No compression for DTLS */
+	if (meth->version != DTLS1_VERSION)
+		ret->comp_methods=SSL_COMP_get_compression_methods();
 
 	ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
 
@@ -1952,8 +1956,10 @@ void SSL_CTX_free(SSL_CTX *a)
 	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)
@@ -2287,7 +2293,7 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)
 #endif
 
 /* THIS NEEDS CLEANING UP */
-X509 *ssl_get_server_send_cert(SSL *s)
+CERT_PKEY *ssl_get_server_send_pkey(const SSL *s)
 	{
 	unsigned long alg_k,alg_a;
 	CERT *c;
@@ -2342,12 +2348,20 @@ X509 *ssl_get_server_send_cert(SSL *s)
 		i=SSL_PKEY_GOST01;
 	else /* if (alg_a & SSL_aNULL) */
 		{
-		SSLerr(SSL_F_SSL_GET_SERVER_SEND_CERT,ERR_R_INTERNAL_ERROR);
+		SSLerr(SSL_F_SSL_GET_SERVER_SEND_PKEY,ERR_R_INTERNAL_ERROR);
 		return(NULL);
 		}
-	if (c->pkeys[i].x509 == NULL) return(NULL);
 
-	return(c->pkeys[i].x509);
+	return c->pkeys + i;
+	}
+
+X509 *ssl_get_server_send_cert(const SSL *s)
+	{
+	CERT_PKEY *cpk;
+	cpk = ssl_get_server_send_pkey(s);
+	if (!cpk)
+		return NULL;
+	return cpk->x509;
 	}
 
 EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *cipher, const EVP_MD **pmd)
@@ -2608,7 +2622,7 @@ const char *SSL_get_version(const SSL *s)
 		return("TLSv1.2");
 	else if (s->version == TLS1_1_VERSION)
 		return("TLSv1.1");
-	if (s->version == TLS1_VERSION)
+	else if (s->version == TLS1_VERSION)
 		return("TLSv1");
 	else if (s->version == SSL3_VERSION)
 		return("SSLv3");
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index d87fd51cfa..e485907748 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -215,6 +215,15 @@
 			 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
 			 *((c)++)=(unsigned char)(((l)    )&0xff))
 
+#define l2n8(l,c)	(*((c)++)=(unsigned char)(((l)>>56)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>48)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>40)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>32)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>24)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+			 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+			 *((c)++)=(unsigned char)(((l)    )&0xff))
+
 #define n2l6(c,l)	(l =((BN_ULLONG)(*((c)++)))<<40, \
 			 l|=((BN_ULLONG)(*((c)++)))<<32, \
 			 l|=((BN_ULLONG)(*((c)++)))<<24, \
@@ -612,6 +621,8 @@ extern SSL3_ENC_METHOD TLSv1_enc_data;
 extern SSL3_ENC_METHOD SSLv3_enc_data;
 extern SSL3_ENC_METHOD DTLSv1_enc_data;
 
+#define SSL_IS_DTLS(s) (s->method->version == DTLS1_VERSION)
+
 #define IMPLEMENT_tls_meth_func(version, func_name, s_accept, s_connect, \
 				s_get_meth) \
 const SSL_METHOD *func_name(void)  \
@@ -830,13 +841,15 @@ int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk);
 int ssl_undefined_function(SSL *s);
 int ssl_undefined_void_function(void);
 int ssl_undefined_const_function(const SSL *s);
-X509 *ssl_get_server_send_cert(SSL *);
+CERT_PKEY *ssl_get_server_send_pkey(const SSL *s);
+X509 *ssl_get_server_send_cert(const SSL *);
 EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *c, const EVP_MD **pmd);
 int ssl_cert_type(X509 *x,EVP_PKEY *pkey);
 void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher);
 STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s);
 int ssl_verify_alarm_type(long type);
 void ssl_load_ciphers(void);
+int ssl_fill_hello_random(SSL *s, int server, unsigned char *field, int len);
 
 int ssl2_enc_init(SSL *s, int client);
 int ssl2_generate_key_material(SSL *s);
@@ -1088,7 +1101,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *d,
 int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
 int ssl_prepare_clienthello_tlsext(SSL *s);
 int ssl_prepare_serverhello_tlsext(SSL *s);
-int ssl_check_clienthello_tlsext(SSL *s);
+int ssl_check_clienthello_tlsext_early(SSL *s);
+int ssl_check_clienthello_tlsext_late(SSL *s);
 int ssl_check_serverhello_tlsext(SSL *s);
 
 #ifndef OPENSSL_NO_HEARTBEATS
@@ -1131,4 +1145,33 @@ int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al
 int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, int maxlen);
 int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len,int *al);
 
+/* s3_cbc.c */
+void ssl3_cbc_copy_mac(unsigned char* out,
+		       const SSL3_RECORD *rec,
+		       unsigned md_size,unsigned orig_len);
+int ssl3_cbc_remove_padding(const SSL* s,
+			    SSL3_RECORD *rec,
+			    unsigned block_size,
+			    unsigned mac_size);
+int tls1_cbc_remove_padding(const SSL* s,
+			    SSL3_RECORD *rec,
+			    unsigned block_size,
+			    unsigned mac_size);
+char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx);
+void ssl3_cbc_digest_record(
+	const EVP_MD_CTX *ctx,
+	unsigned char* md_out,
+	size_t* md_out_size,
+	const unsigned char header[13],
+	const unsigned char *data,
+	size_t data_plus_mac_size,
+	size_t data_plus_mac_plus_padding_size,
+	const unsigned char *mac_secret,
+	unsigned mac_secret_length,
+	char is_sslv3);
+
+void tls_fips_digest_extra(
+	const EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *mac_ctx,
+	const unsigned char *data, size_t data_len, size_t orig_len);
+
 #endif
diff --git a/src/lib/libssl/ssl_rsa.c b/src/lib/libssl/ssl_rsa.c
index c0960b5712..60e7b66859 100644
--- a/src/lib/libssl/ssl_rsa.c
+++ b/src/lib/libssl/ssl_rsa.c
@@ -710,7 +710,7 @@ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
 
 	ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */
 
-	in=BIO_new(BIO_s_file_internal());
+	in = BIO_new(BIO_s_file_internal());
 	if (in == NULL)
 		{
 		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_BUF_LIB);
@@ -723,14 +723,16 @@ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
 		goto end;
 		}
 
-	x=PEM_read_bio_X509_AUX(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
+	x=PEM_read_bio_X509_AUX(in,NULL,ctx->default_passwd_callback,
+				ctx->default_passwd_callback_userdata);
 	if (x == NULL)
 		{
 		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_PEM_LIB);
 		goto end;
 		}
 
-	ret=SSL_CTX_use_certificate(ctx,x);
+	ret = SSL_CTX_use_certificate(ctx, x);
+
 	if (ERR_peek_error() != 0)
 		ret = 0;  /* Key/certificate mismatch doesn't imply ret==0 ... */
 	if (ret)
@@ -742,13 +744,15 @@ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
 		int r;
 		unsigned long err;
 		
-		if (ctx->extra_certs != NULL) 
+		if (ctx->extra_certs != NULL)
 			{
 			sk_X509_pop_free(ctx->extra_certs, X509_free);
 			ctx->extra_certs = NULL;
 			}
 
-		while ((ca = PEM_read_bio_X509(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata))
+		while ((ca = PEM_read_bio_X509(in, NULL,
+					ctx->default_passwd_callback,
+					ctx->default_passwd_callback_userdata))
 			!= NULL)
 			{
 			r = SSL_CTX_add_extra_chain_cert(ctx, ca);
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c
index f7bdeb3b9d..0c4cddedf8 100644
--- a/src/lib/libssl/t1_enc.c
+++ b/src/lib/libssl/t1_enc.c
@@ -361,7 +361,7 @@ int tls1_change_cipher_state(SSL *s, int which)
 	{
         int i;
         for (i=0; i<s->s3->tmp.key_block_length; i++)
-		printf("%02x", key_block[i]);  printf("\n");
+		printf("%02x", s->s3->tmp.key_block[i]);  printf("\n");
         }
 #endif	/* KSSL_DEBUG */
 
@@ -414,15 +414,20 @@ int tls1_change_cipher_state(SSL *s, int which)
 			s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM;
 			else
 			s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM;
-		if (s->enc_write_ctx != NULL)
+		if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s))
 			reuse_dd = 1;
-		else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
+		else if ((s->enc_write_ctx=EVP_CIPHER_CTX_new()) == NULL)
 			goto err;
-		else
-			/* make sure it's intialized in case we exit later with an error */
-			EVP_CIPHER_CTX_init(s->enc_write_ctx);
 		dd= s->enc_write_ctx;
-		mac_ctx = ssl_replace_hash(&s->write_hash,NULL);
+		if (SSL_IS_DTLS(s))
+			{
+			mac_ctx = EVP_MD_CTX_create();
+			if (!mac_ctx)
+				goto err;
+			s->write_hash = mac_ctx;
+			}
+		else
+			mac_ctx = ssl_replace_hash(&s->write_hash,NULL);
 #ifndef OPENSSL_NO_COMP
 		if (s->compress != NULL)
 			{
@@ -667,12 +672,21 @@ err:
 	return(ret);
 	}
 
+/* tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
+ *
+ * Returns:
+ *   0: (in non-constant time) if the record is publically invalid (i.e. too
+ *       short etc).
+ *   1: if the record's padding is valid / the encryption was successful.
+ *   -1: if the record's padding/AEAD-authenticator is invalid or, if sending,
+ *       an internal error occured.
+ */
 int tls1_enc(SSL *s, int send)
 	{
 	SSL3_RECORD *rec;
 	EVP_CIPHER_CTX *ds;
 	unsigned long l;
-	int bs,i,ii,j,k,pad=0;
+	int bs,i,j,k,pad=0,ret,mac_size=0;
 	const EVP_CIPHER *enc;
 
 	if (send)
@@ -729,11 +743,11 @@ int tls1_enc(SSL *s, int send)
 	printf("tls1_enc(%d)\n", send);
 #endif    /* KSSL_DEBUG */
 
-	if ((s->session == NULL) || (ds == NULL) ||
-		(enc == NULL))
+	if ((s->session == NULL) || (ds == NULL) || (enc == NULL))
 		{
 		memmove(rec->data,rec->input,rec->length);
 		rec->input=rec->data;
+		ret = 1;
 		}
 	else
 		{
@@ -797,13 +811,13 @@ int tls1_enc(SSL *s, int send)
 
 #ifdef KSSL_DEBUG
 		{
-                unsigned long ui;
+		unsigned long ui;
 		printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
-                        ds,rec->data,rec->input,l);
+			ds,rec->data,rec->input,l);
 		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
-                        ds->buf_len, ds->cipher->key_len,
-                        DES_KEY_SZ, DES_SCHEDULE_SZ,
-                        ds->cipher->iv_len);
+			ds->buf_len, ds->cipher->key_len,
+			DES_KEY_SZ, DES_SCHEDULE_SZ,
+			ds->cipher->iv_len);
 		printf("\t\tIV: ");
 		for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
 		printf("\n");
@@ -816,13 +830,7 @@ int tls1_enc(SSL *s, int send)
 		if (!send)
 			{
 			if (l == 0 || l%bs != 0)
-				{
-				if (s->version >= TLS1_1_VERSION)
-					return -1;
-				SSLerr(SSL_F_TLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
-				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED);
 				return 0;
-				}
 			}
 		
 		i = EVP_Cipher(ds,rec->data,rec->input,l);
@@ -839,68 +847,24 @@ int tls1_enc(SSL *s, int send)
 
 #ifdef KSSL_DEBUG
 		{
-                unsigned long i;
-                printf("\trec->data=");
+		unsigned long i;
+		printf("\trec->data=");
 		for (i=0; i<l; i++)
-                        printf(" %02x", rec->data[i]);  printf("\n");
-                }
+			printf(" %02x", rec->data[i]);  printf("\n");
+		}
 #endif	/* KSSL_DEBUG */
 
+		ret = 1;
+		if (EVP_MD_CTX_md(s->read_hash) != NULL)
+			mac_size = EVP_MD_CTX_size(s->read_hash);
 		if ((bs != 1) && !send)
-			{
-			ii=i=rec->data[l-1]; /* padding_length */
-			i++;
-			/* NB: if compression is in operation the first packet
-			 * may not be of even length so the padding bug check
-			 * cannot be performed. This bug workaround has been
-			 * around since SSLeay so hopefully it is either fixed
-			 * now or no buggy implementation supports compression 
-			 * [steve]
-			 */
-			if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG)
-				&& !s->expand)
-				{
-				/* First packet is even in size, so check */
-				if ((memcmp(s->s3->read_sequence,
-					"\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1))
-					s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
-				if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
-					i--;
-				}
-			/* TLS 1.0 does not bound the number of padding bytes by the block size.
-			 * All of them must have value 'padding_length'. */
-			if (i > (int)rec->length)
-				{
-				/* Incorrect padding. SSLerr() and ssl3_alert are done
-				 * by caller: we don't want to reveal whether this is
-				 * a decryption error or a MAC verification failure
-				 * (see http://www.openssl.org/~bodo/tls-cbc.txt) */
-				return -1;
-				}
-			for (j=(int)(l-i); j<(int)l; j++)
-				{
-				if (rec->data[j] != ii)
-					{
-					/* Incorrect padding */
-					return -1;
-					}
-				}
-			rec->length -=i;
-			if (s->version >= TLS1_1_VERSION
-				&& EVP_CIPHER_CTX_mode(ds) == EVP_CIPH_CBC_MODE)
-				{
-				if (bs > (int)rec->length)
-					return -1;
-				rec->data += bs;    /* skip the explicit IV */
-				rec->input += bs;
-				rec->length -= bs;
-				}
-			}
+			ret = tls1_cbc_remove_padding(s, rec, bs, mac_size);
 		if (pad && !send)
 			rec->length -= pad;
 		}
-	return(1);
+	return ret;
 	}
+
 int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out)
 	{
 	unsigned int ret;
@@ -956,18 +920,19 @@ int tls1_final_finish_mac(SSL *s,
 		if (mask & ssl_get_algorithm2(s))
 			{
 			int hashsize = EVP_MD_size(md);
-			if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
+			EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx];
+			if (!hdgst || hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
 				{
 				/* internal error: 'buf' is too small for this cipersuite! */
 				err = 1;
 				}
 			else
 				{
-				EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
-				EVP_DigestFinal_ex(&ctx,q,&i);
-				if (i != (unsigned int)hashsize) /* can't really happen */
+				if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
+					!EVP_DigestFinal_ex(&ctx,q,&i) ||
+					(i != (unsigned int)hashsize))
 					err = 1;
-				q+=i;
+				q+=hashsize;
 				}
 			}
 		}
@@ -990,10 +955,10 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
 	SSL3_RECORD *rec;
 	unsigned char *seq;
 	EVP_MD_CTX *hash;
-	size_t md_size;
+	size_t md_size, orig_len;
 	int i;
 	EVP_MD_CTX hmac, *mac_ctx;
-	unsigned char buf[5]; 
+	unsigned char header[13];
 	int stream_mac = (send?(ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM):(ssl->mac_flags&SSL_MAC_FLAG_READ_MAC_STREAM));
 	int t;
 
@@ -1014,12 +979,6 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
 	OPENSSL_assert(t >= 0);
 	md_size=t;
 
-	buf[0]=rec->type;
-	buf[1]=(unsigned char)(ssl->version>>8);
-	buf[2]=(unsigned char)(ssl->version);
-	buf[3]=rec->length>>8;
-	buf[4]=rec->length&0xff;
-
 	/* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */
 	if (stream_mac) 
 		{
@@ -1027,7 +986,8 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
 		}
 		else
 		{
-			EVP_MD_CTX_copy(&hmac,hash);
+			if (!EVP_MD_CTX_copy(&hmac,hash))
+				return -1;
 			mac_ctx = &hmac;
 		}
 
@@ -1038,17 +998,55 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
 		s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p);
 		memcpy (p,&seq[2],6);
 
-		EVP_DigestSignUpdate(mac_ctx,dtlsseq,8);
+		memcpy(header, dtlsseq, 8);
 		}
 	else
-		EVP_DigestSignUpdate(mac_ctx,seq,8);
+		memcpy(header, seq, 8);
+
+	/* kludge: tls1_cbc_remove_padding passes padding length in rec->type */
+	orig_len = rec->length+md_size+((unsigned int)rec->type>>8);
+	rec->type &= 0xff;
 
-	EVP_DigestSignUpdate(mac_ctx,buf,5);
-	EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length);
-	t=EVP_DigestSignFinal(mac_ctx,md,&md_size);
-	OPENSSL_assert(t > 0);
+	header[8]=rec->type;
+	header[9]=(unsigned char)(ssl->version>>8);
+	header[10]=(unsigned char)(ssl->version);
+	header[11]=(rec->length)>>8;
+	header[12]=(rec->length)&0xff;
+
+	if (!send &&
+	    EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+	    ssl3_cbc_record_digest_supported(mac_ctx))
+		{
+		/* This is a CBC-encrypted record. We must avoid leaking any
+		 * timing-side channel information about how many blocks of
+		 * data we are hashing because that gives an attacker a
+		 * timing-oracle. */
+		ssl3_cbc_digest_record(
+			mac_ctx,
+			md, &md_size,
+			header, rec->input,
+			rec->length + md_size, orig_len,
+			ssl->s3->read_mac_secret,
+			ssl->s3->read_mac_secret_size,
+			0 /* not SSLv3 */);
+		}
+	else
+		{
+		EVP_DigestSignUpdate(mac_ctx,header,sizeof(header));
+		EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length);
+		t=EVP_DigestSignFinal(mac_ctx,md,&md_size);
+		OPENSSL_assert(t > 0);
+#ifdef OPENSSL_FIPS
+		if (!send && FIPS_mode())
+			tls_fips_digest_extra(
+	    				ssl->enc_read_ctx,
+					mac_ctx, rec->input,
+					rec->length, orig_len);
+#endif
+		}
 		
-	if (!stream_mac) EVP_MD_CTX_cleanup(&hmac);
+	if (!stream_mac)
+		EVP_MD_CTX_cleanup(&hmac);
 #ifdef TLS_DEBUG
 printf("sec=");
 {unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); }
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c
index 27c8e3460d..bddffd92cc 100644
--- a/src/lib/libssl/t1_lib.c
+++ b/src/lib/libssl/t1_lib.c
@@ -342,19 +342,11 @@ static unsigned char tls12_sigalgs[] = {
 #ifndef OPENSSL_NO_SHA
 	tlsext_sigalg(TLSEXT_hash_sha1)
 #endif
-#ifndef OPENSSL_NO_MD5
-	tlsext_sigalg_rsa(TLSEXT_hash_md5)
-#endif
 };
 
 int tls12_get_req_sig_algs(SSL *s, unsigned char *p)
 	{
 	size_t slen = sizeof(tls12_sigalgs);
-#ifdef OPENSSL_FIPS
-	/* If FIPS mode don't include MD5 which is last */
-	if (FIPS_mode())
-		slen -= 2;
-#endif
 	if (p)
 		memcpy(p, tls12_sigalgs, slen);
 	return (int)slen;
@@ -649,6 +641,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
 		}
 #endif
 
+#ifndef OPENSSL_NO_SRTP
         if(SSL_get_srtp_profiles(s))
                 {
                 int el;
@@ -667,6 +660,37 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
 			}
                 ret += el;
                 }
+#endif
+
+#ifdef TLSEXT_TYPE_padding
+	/* Add padding to workaround bugs in F5 terminators.
+	 * See https://tools.ietf.org/html/draft-agl-tls-padding-03
+	 *
+	 * NB: because this code works out the length of all existing
+	 * extensions it MUST always appear last.
+	 */
+	{
+	int hlen = ret - (unsigned char *)s->init_buf->data;
+	/* The code in s23_clnt.c to build ClientHello messages includes the
+	 * 5-byte record header in the buffer, while the code in s3_clnt.c does
+	 * not. */
+	if (s->state == SSL23_ST_CW_CLNT_HELLO_A)
+		hlen -= 5;
+	if (hlen > 0xff && hlen < 0x200)
+		{
+		hlen = 0x200 - hlen;
+		if (hlen >= 4)
+			hlen -= 4;
+		else
+			hlen = 0;
+
+		s2n(TLSEXT_TYPE_padding, ret);
+		s2n(hlen, ret);
+		memset(ret, 0, hlen);
+		ret += hlen;
+		}
+	}
+#endif
 
 	if ((extdatalen = ret-p-2)== 0) 
 		return p;
@@ -781,6 +805,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
 		}
 #endif
 
+#ifndef OPENSSL_NO_SRTP
         if(s->srtp_profile)
                 {
                 int el;
@@ -799,6 +824,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
 			}
                 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))
@@ -862,6 +888,89 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
 	return ret;
 	}
 
+#ifndef OPENSSL_NO_EC
+/* ssl_check_for_safari attempts to fingerprint Safari using OS X
+ * SecureTransport using the TLS extension block in |d|, of length |n|.
+ * Safari, since 10.6, sends exactly these extensions, in this order:
+ *   SNI,
+ *   elliptic_curves
+ *   ec_point_formats
+ *
+ * We wish to fingerprint Safari because they broke ECDHE-ECDSA support in 10.8,
+ * but they advertise support. So enabling ECDHE-ECDSA ciphers breaks them.
+ * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from
+ * 10.8..10.8.3 (which don't work).
+ */
+static void ssl_check_for_safari(SSL *s, const unsigned char *data, const unsigned char *d, int n) {
+	unsigned short type, size;
+	static const unsigned char kSafariExtensionsBlock[] = {
+		0x00, 0x0a,  /* elliptic_curves extension */
+		0x00, 0x08,  /* 8 bytes */
+		0x00, 0x06,  /* 6 bytes of curve ids */
+		0x00, 0x17,  /* P-256 */
+		0x00, 0x18,  /* P-384 */
+		0x00, 0x19,  /* P-521 */
+
+		0x00, 0x0b,  /* ec_point_formats */
+		0x00, 0x02,  /* 2 bytes */
+		0x01,        /* 1 point format */
+		0x00,        /* uncompressed */
+	};
+
+	/* The following is only present in TLS 1.2 */
+	static const unsigned char kSafariTLS12ExtensionsBlock[] = {
+		0x00, 0x0d,  /* signature_algorithms */
+		0x00, 0x0c,  /* 12 bytes */
+		0x00, 0x0a,  /* 10 bytes */
+		0x05, 0x01,  /* SHA-384/RSA */
+		0x04, 0x01,  /* SHA-256/RSA */
+		0x02, 0x01,  /* SHA-1/RSA */
+		0x04, 0x03,  /* SHA-256/ECDSA */
+		0x02, 0x03,  /* SHA-1/ECDSA */
+	};
+
+	if (data >= (d+n-2))
+		return;
+	data += 2;
+
+	if (data > (d+n-4))
+		return;
+	n2s(data,type);
+	n2s(data,size);
+
+	if (type != TLSEXT_TYPE_server_name)
+		return;
+
+	if (data+size > d+n)
+		return;
+	data += size;
+
+	if (TLS1_get_client_version(s) >= TLS1_2_VERSION)
+		{
+		const size_t len1 = sizeof(kSafariExtensionsBlock);
+		const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock);
+
+		if (data + len1 + len2 != d+n)
+			return;
+		if (memcmp(data, kSafariExtensionsBlock, len1) != 0)
+			return;
+		if (memcmp(data + len1, kSafariTLS12ExtensionsBlock, len2) != 0)
+			return;
+		}
+	else
+		{
+		const size_t len = sizeof(kSafariExtensionsBlock);
+
+		if (data + len != d+n)
+			return;
+		if (memcmp(data, kSafariExtensionsBlock, len) != 0)
+			return;
+		}
+
+	s->s3->is_probably_safari = 1;
+}
+#endif /* !OPENSSL_NO_EC */
+
 int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
 	{
 	unsigned short type;
@@ -882,6 +991,11 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
 	                       SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
 #endif
 
+#ifndef OPENSSL_NO_EC
+	if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
+		ssl_check_for_safari(s, data, d, n);
+#endif /* !OPENSSL_NO_EC */
+
 	if (data >= (d+n-2))
 		goto ri_check;
 	n2s(data,len);
@@ -1077,7 +1191,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
 			int ellipticcurvelist_length = (*(sdata++) << 8);
 			ellipticcurvelist_length += (*(sdata++));
 
-			if (ellipticcurvelist_length != size - 2)
+			if (ellipticcurvelist_length != size - 2 ||
+				ellipticcurvelist_length < 1)
 				{
 				*al = TLS1_AD_DECODE_ERROR;
 				return 0;
@@ -1176,7 +1291,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
 				}
 			}
 		else if (type == TLSEXT_TYPE_status_request &&
-		         s->version != DTLS1_VERSION && s->ctx->tlsext_status_cb)
+		         s->version != DTLS1_VERSION)
 			{
 		
 			if (size < 5) 
@@ -1328,12 +1443,14 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
 #endif
 
 		/* 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;
 		}
@@ -1433,7 +1550,8 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
 			unsigned char *sdata = data;
 			int ecpointformatlist_length = *(sdata++);
 
-			if (ecpointformatlist_length != size - 1)
+			if (ecpointformatlist_length != size - 1 || 
+				ecpointformatlist_length < 1)
 				{
 				*al = TLS1_AD_DECODE_ERROR;
 				return 0;
@@ -1527,7 +1645,7 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
 			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;
@@ -1577,12 +1695,14 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
 				}
 			}
 #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;		
 		}
@@ -1763,7 +1883,7 @@ int ssl_prepare_serverhello_tlsext(SSL *s)
 	return 1;
 	}
 
-int ssl_check_clienthello_tlsext(SSL *s)
+int ssl_check_clienthello_tlsext_early(SSL *s)
 	{
 	int ret=SSL_TLSEXT_ERR_NOACK;
 	int al = SSL_AD_UNRECOGNIZED_NAME;
@@ -1782,42 +1902,12 @@ int ssl_check_clienthello_tlsext(SSL *s)
 	else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0) 		
 		ret = s->initial_ctx->tlsext_servername_callback(s, &al, s->initial_ctx->tlsext_servername_arg);
 
-	/* If status request then ask callback what to do.
- 	 * Note: this must be called after servername callbacks in case 
- 	 * the certificate has changed.
- 	 */
-	if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb)
-		{
-		int r;
-		r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
-		switch (r)
-			{
-			/* We don't want to send a status request response */
-			case SSL_TLSEXT_ERR_NOACK:
-				s->tlsext_status_expected = 0;
-				break;
-			/* status request response should be sent */
-			case SSL_TLSEXT_ERR_OK:
-				if (s->tlsext_ocsp_resp)
-					s->tlsext_status_expected = 1;
-				else
-					s->tlsext_status_expected = 0;
-				break;
-			/* something bad happened */
-			case SSL_TLSEXT_ERR_ALERT_FATAL:
-				ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-				al = SSL_AD_INTERNAL_ERROR;
-				goto err;
-			}
-		}
-	else
-		s->tlsext_status_expected = 0;
-
 #ifdef TLSEXT_TYPE_opaque_prf_input
  	{
 		/* This sort of belongs into ssl_prepare_serverhello_tlsext(),
 		 * but we might be sending an alert in response to the client hello,
-		 * so this has to happen here in ssl_check_clienthello_tlsext(). */
+		 * so this has to happen here in
+		 * ssl_check_clienthello_tlsext_early(). */
 
 		int r = 1;
 	
@@ -1869,8 +1959,8 @@ int ssl_check_clienthello_tlsext(SSL *s)
 			}
 	}
 
-#endif
  err:
+#endif
 	switch (ret)
 		{
 		case SSL_TLSEXT_ERR_ALERT_FATAL:
@@ -1888,6 +1978,71 @@ int ssl_check_clienthello_tlsext(SSL *s)
 		}
 	}
 
+int ssl_check_clienthello_tlsext_late(SSL *s)
+	{
+	int ret = SSL_TLSEXT_ERR_OK;
+	int al;
+
+	/* If status request then ask callback what to do.
+ 	 * Note: this must be called after servername callbacks in case 
+ 	 * the certificate has changed, and must be called after the cipher
+	 * has been chosen because this may influence which certificate is sent
+ 	 */
+	if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb)
+		{
+		int r;
+		CERT_PKEY *certpkey;
+		certpkey = ssl_get_server_send_pkey(s);
+		/* If no certificate can't return certificate status */
+		if (certpkey == NULL)
+			{
+			s->tlsext_status_expected = 0;
+			return 1;
+			}
+		/* Set current certificate to one we will use so
+		 * SSL_get_certificate et al can pick it up.
+		 */
+		s->cert->key = certpkey;
+		r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
+		switch (r)
+			{
+			/* We don't want to send a status request response */
+			case SSL_TLSEXT_ERR_NOACK:
+				s->tlsext_status_expected = 0;
+				break;
+			/* status request response should be sent */
+			case SSL_TLSEXT_ERR_OK:
+				if (s->tlsext_ocsp_resp)
+					s->tlsext_status_expected = 1;
+				else
+					s->tlsext_status_expected = 0;
+				break;
+			/* something bad happened */
+			case SSL_TLSEXT_ERR_ALERT_FATAL:
+				ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+				al = SSL_AD_INTERNAL_ERROR;
+				goto err;
+			}
+		}
+	else
+		s->tlsext_status_expected = 0;
+
+ err:
+	switch (ret)
+		{
+		case SSL_TLSEXT_ERR_ALERT_FATAL:
+			ssl3_send_alert(s,SSL3_AL_FATAL,al); 
+			return -1;
+
+		case SSL_TLSEXT_ERR_ALERT_WARNING:
+			ssl3_send_alert(s,SSL3_AL_WARNING,al);
+			return 1; 
+
+		default:
+			return 1;
+		}
+	}
+
 int ssl_check_serverhello_tlsext(SSL *s)
 	{
 	int ret=SSL_TLSEXT_ERR_NOACK;
@@ -2189,7 +2344,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
 	HMAC_Update(&hctx, etick, eticklen);
 	HMAC_Final(&hctx, tick_hmac, NULL);
 	HMAC_CTX_cleanup(&hctx);
-	if (memcmp(tick_hmac, etick + eticklen, mlen))
+	if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen))
 		return 2;
 	/* Attempt to decrypt session data */
 	/* Move p after IV to start of encrypted ticket, update length */
@@ -2319,14 +2474,6 @@ const EVP_MD *tls12_get_hash(unsigned char hash_alg)
 	{
 	switch(hash_alg)
 		{
-#ifndef OPENSSL_NO_MD5
-		case TLSEXT_hash_md5:
-#ifdef OPENSSL_FIPS
-		if (FIPS_mode())
-			return NULL;
-#endif
-		return EVP_md5();
-#endif
 #ifndef OPENSSL_NO_SHA
 		case TLSEXT_hash_sha1:
 		return EVP_sha1();
@@ -2414,7 +2561,7 @@ int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize)
 	 */
 #ifndef OPENSSL_NO_DSA
 	if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest)
-		c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_dss1();
+		c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
 #endif
 #ifndef OPENSSL_NO_RSA
 	if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest)
@@ -2425,7 +2572,7 @@ int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize)
 #endif
 #ifndef OPENSSL_NO_ECDSA
 	if (!c->pkeys[SSL_PKEY_ECC].digest)
-		c->pkeys[SSL_PKEY_ECC].digest = EVP_ecdsa();
+		c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
 #endif
 	return 1;
 	}
@@ -2441,16 +2588,20 @@ tls1_process_heartbeat(SSL *s)
 	unsigned int payload;
 	unsigned int padding = 16; /* Use minimum padding */
 
-	/* Read type and payload length first */
-	hbtype = *p++;
-	n2s(p, payload);
-	pl = p;
-
 	if (s->msg_callback)
 		s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
 			&s->s3->rrec.data[0], s->s3->rrec.length,
 			s, s->msg_callback_arg);
 
+	/* Read type and payload length first */
+	if (1 + 2 + 16 > s->s3->rrec.length)
+		return 0; /* silently discard */
+	hbtype = *p++;
+	n2s(p, payload);
+	if (1 + 2 + payload + 16 > s->s3->rrec.length)
+		return 0; /* silently discard per RFC 6520 sec. 4 */
+	pl = p;
+
 	if (hbtype == TLS1_HB_REQUEST)
 		{
 		unsigned char *buffer, *bp;
diff --git a/src/lib/libssl/test/cms-test.pl b/src/lib/libssl/test/cms-test.pl
index c938bcf00d..dfef799be2 100644
--- a/src/lib/libssl/test/cms-test.pl
+++ b/src/lib/libssl/test/cms-test.pl
@@ -415,8 +415,10 @@ sub run_smime_tests {
 }
 
 sub cmp_files {
+    use FileHandle;
     my ( $f1, $f2 ) = @_;
-    my ( $fp1, $fp2 );
+    my $fp1 = FileHandle->new();
+    my $fp2 = FileHandle->new();
 
     my ( $rd1, $rd2 );
 
diff --git a/src/lib/libssl/test/testssl b/src/lib/libssl/test/testssl
index 5ae4dc8720..4e8542b556 100644
--- a/src/lib/libssl/test/testssl
+++ b/src/lib/libssl/test/testssl
@@ -119,6 +119,23 @@ $ssltest -bio_pair -server_auth -client_auth $CA $extra || exit 1
 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 `../util/shlib_wrap.sh ../apps/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 ../util/shlib_wrap.sh ../apps/openssl no-dh; then
diff --git a/src/lib/libssl/tls1.h b/src/lib/libssl/tls1.h
index c39c267f0b..c992091e30 100644
--- a/src/lib/libssl/tls1.h
+++ b/src/lib/libssl/tls1.h
@@ -230,6 +230,12 @@ extern "C" {
 /* ExtensionType value from RFC5620 */
 #define TLSEXT_TYPE_heartbeat	15
 
+/* ExtensionType value for TLS padding extension.
+ * http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
+ * http://tools.ietf.org/html/draft-agl-tls-padding-03
+ */
+#define TLSEXT_TYPE_padding	21
+
 /* ExtensionType value from RFC4507 */
 #define TLSEXT_TYPE_session_ticket		35
 
-- 
cgit v1.2.3-55-g6feb