am 2b5a3d1f: am 0f2dac0f: resolved conflicts for merge of 69c63910 to jb-mr2-dev-plus-aosp

* commit '2b5a3d1f368ebada581192f8aca1a48335987620':
  Add support for TLS_FALLBACK_SCSV
diff --git a/Android.mk b/Android.mk
index 9f5834e..46af985 100644
--- a/Android.mk
+++ b/Android.mk
@@ -7,7 +7,11 @@
 # These makefiles are here instead of being Android.mk files in the
 # respective crypto, ssl, and apps directories so
 # that import_openssl.sh import won't remove them.
-include $(LOCAL_PATH)/build-config.mk
+ifeq ($(strip $(TARGET_IS_64_BIT)),true)
+  include $(LOCAL_PATH)/build-config-64.mk
+else
+  include $(LOCAL_PATH)/build-config-32.mk
+endif
 include $(LOCAL_PATH)/Crypto.mk
 include $(LOCAL_PATH)/Ssl.mk
 include $(LOCAL_PATH)/Apps.mk
diff --git a/Apps-config.mk b/Apps-config.mk
index 2ee8026..bc67db2 100644
--- a/Apps-config.mk
+++ b/Apps-config.mk
@@ -1,6 +1,6 @@
 # Auto-generated - DO NOT EDIT!
 # To regenerate, edit openssl.config, then run:
-#     ./import_openssl.sh import /path/to/openssl-1.0.1e.tar.gz
+#     ./import_openssl.sh import /path/to/openssl-1.0.1f.tar.gz
 #
 # Before including this file, the local Android.mk must define the following
 # variables:
@@ -35,6 +35,7 @@
   apps/asn1pars.c \
   apps/ca.c \
   apps/ciphers.c \
+  apps/cms.c \
   apps/crl.c \
   apps/crl2p7.c \
   apps/dgst.c \
@@ -90,6 +91,12 @@
 
 arm_exclude_files :=
 
+arm64_c_flags :=
+
+arm64_src_files :=
+
+arm64_exclude_files :=
+
 x86_c_flags :=
 
 x86_src_files :=
diff --git a/Crypto-config.mk b/Crypto-config.mk
index d74a791..b5b9a5f 100644
--- a/Crypto-config.mk
+++ b/Crypto-config.mk
@@ -1,6 +1,6 @@
 # Auto-generated - DO NOT EDIT!
 # To regenerate, edit openssl.config, then run:
-#     ./import_openssl.sh import /path/to/openssl-1.0.1e.tar.gz
+#     ./import_openssl.sh import /path/to/openssl-1.0.1f.tar.gz
 #
 # Before including this file, the local Android.mk must define the following
 # variables:
@@ -171,6 +171,19 @@
   crypto/cmac/cm_ameth.c \
   crypto/cmac/cm_pmeth.c \
   crypto/cmac/cmac.c \
+  crypto/cms/cms_asn1.c \
+  crypto/cms/cms_att.c \
+  crypto/cms/cms_cd.c \
+  crypto/cms/cms_dd.c \
+  crypto/cms/cms_enc.c \
+  crypto/cms/cms_env.c \
+  crypto/cms/cms_err.c \
+  crypto/cms/cms_ess.c \
+  crypto/cms/cms_io.c \
+  crypto/cms/cms_lib.c \
+  crypto/cms/cms_pwri.c \
+  crypto/cms/cms_sd.c \
+  crypto/cms/cms_smime.c \
   crypto/comp/c_rle.c \
   crypto/comp/c_zlib.c \
   crypto/comp/comp_err.c \
@@ -562,6 +575,13 @@
 arm_exclude_files := \
   crypto/aes/aes_core.c \
 
+arm64_c_flags := \
+  -DOPENSSL_NO_ASM \
+
+arm64_src_files :=
+
+arm64_exclude_files :=
+
 x86_c_flags := \
   -DAES_ASM \
   -DDES_PTR \
@@ -641,8 +661,10 @@
 x86_64_exclude_files := \
   crypto/aes/aes_cbc.c \
   crypto/aes/aes_core.c \
+  crypto/bn/bn_asm.c \
   crypto/mem_clr.c \
   crypto/rc4/rc4_enc.c \
+  crypto/rc4/rc4_skey.c \
 
 mips_c_flags := \
   -DAES_ASM \
diff --git a/Crypto.mk b/Crypto.mk
index 7bb313b..bcfd141 100644
--- a/Crypto.mk
+++ b/Crypto.mk
@@ -13,11 +13,10 @@
 
 LOCAL_SHARED_LIBRARIES := $(log_shared_libraries)
 
-# If we're building an unbundled build, don't try to use clang since it's not
-# in the NDK yet. This can be removed when a clang version that is fast enough
-# in the NDK.
-ifeq (,$(TARGET_BUILD_APPS))
-LOCAL_CLANG := true
+# The static library should be used in only unbundled apps
+# and we don't have clang in unbundled build yet.
+ifeq ($(TARGET_ARCH),arm64)
+$(info TODOArm64: $(LOCAL_PATH)/Android.mk : Use NDK once it is available for Arm64)
 else
 LOCAL_SDK_VERSION := 9
 endif
diff --git a/Ssl-config.mk b/Ssl-config.mk
index e14e4bb..b07c100 100644
--- a/Ssl-config.mk
+++ b/Ssl-config.mk
@@ -1,6 +1,6 @@
 # Auto-generated - DO NOT EDIT!
 # To regenerate, edit openssl.config, then run:
-#     ./import_openssl.sh import /path/to/openssl-1.0.1e.tar.gz
+#     ./import_openssl.sh import /path/to/openssl-1.0.1f.tar.gz
 #
 # Before including this file, the local Android.mk must define the following
 # variables:
@@ -85,6 +85,12 @@
 
 arm_exclude_files :=
 
+arm64_c_flags :=
+
+arm64_src_files :=
+
+arm64_exclude_files :=
+
 x86_c_flags :=
 
 x86_src_files :=
diff --git a/Ssl.mk b/Ssl.mk
index 47ccf14..4d1da48 100644
--- a/Ssl.mk
+++ b/Ssl.mk
@@ -11,11 +11,10 @@
 include $(CLEAR_VARS)
 include $(LOCAL_PATH)/android-config.mk
 
-# If we're building an unbundled build, don't try to use clang since it's not
-# in the NDK yet. This can be removed when a clang version that is fast enough
-# in the NDK.
-ifeq (,$(TARGET_BUILD_APPS))
-LOCAL_CLANG := true
+# The static library should be used in only unbundled apps
+# and we don't have clang in unbundled build yet.
+ifeq ($(TARGET_ARCH),arm64)
+$(info TODOArm64: $(LOCAL_PATH)/Android.mk : Use NDK once it is available for Arm64)
 else
 LOCAL_SDK_VERSION := 9
 endif
diff --git a/apps/apps.h b/apps/apps.h
index c1ca99d..3aeb46c 100644
--- a/apps/apps.h
+++ b/apps/apps.h
@@ -188,6 +188,7 @@
 			do { CONF_modules_unload(1); destroy_ui_method(); \
 			OBJ_cleanup(); EVP_cleanup(); ENGINE_cleanup(); \
 			CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); \
+			RAND_cleanup(); \
 			ERR_free_strings(); zlib_cleanup();} while(0)
 #  else
 #    define apps_startup() \
@@ -198,6 +199,7 @@
 			do { CONF_modules_unload(1); destroy_ui_method(); \
 			OBJ_cleanup(); EVP_cleanup(); \
 			CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); \
+			RAND_cleanup(); \
 			ERR_free_strings(); zlib_cleanup(); } while(0)
 #  endif
 #endif
diff --git a/apps/openssl.c b/apps/openssl.c
index 33b1655..a9fa1e3 100644
--- a/apps/openssl.c
+++ b/apps/openssl.c
@@ -117,6 +117,7 @@
 #include "apps.h"
 #include <openssl/bio.h>
 #include <openssl/crypto.h>
+#include <openssl/rand.h>
 #include <openssl/lhash.h>
 #include <openssl/conf.h>
 #include <openssl/x509.h>
diff --git a/apps/pkcs12.c b/apps/pkcs12.c
index b54c6f8..4d62a7b 100644
--- a/apps/pkcs12.c
+++ b/apps/pkcs12.c
@@ -112,7 +112,7 @@
     int maciter = PKCS12_DEFAULT_ITER;
     int twopass = 0;
     int keytype = 0;
-    int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
+    int cert_pbe;
     int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
     int ret = 1;
     int macver = 1;
@@ -130,6 +130,13 @@
 
     apps_startup();
 
+#ifdef OPENSSL_FIPS
+    if (FIPS_mode())
+	cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+    else
+#endif
+    cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
+
     enc = EVP_des_ede3_cbc();
     if (bio_err == NULL ) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
 
diff --git a/apps/s_client.c b/apps/s_client.c
index e8e1c6d..299facd 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -364,6 +364,7 @@
 # endif
 #endif
 	BIO_printf(bio_err," -cutthrough       - enable 1-RTT full-handshake for strong ciphers\n");
+	BIO_printf(bio_err," -no_record_splitting  - disable 1/n-1 record splitting in CBC mode\n");
 	BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
 #ifndef OPENSSL_NO_SRTP
 	BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
@@ -580,7 +581,7 @@
 	EVP_PKEY *key = NULL;
 	char *CApath=NULL,*CAfile=NULL,*cipher=NULL;
 	int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0;
-	int cutthrough=0;
+	int cutthrough=0, no_record_splitting=0;
 	int crlf=0;
 	int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending;
 	SSL_CTX *ctx=NULL;
@@ -595,6 +596,7 @@
 	char *inrand=NULL;
 	int mbuf_len=0;
 	struct timeval timeout, *timeoutp;
+	int ssl_mode;
 #ifndef OPENSSL_NO_ENGINE
 	char *engine_id=NULL;
 	char *ssl_client_engine_id=NULL;
@@ -900,6 +902,8 @@
 #endif
 		else if (strcmp(*argv,"-cutthrough") == 0)
 			cutthrough=1;
+		else if (strcmp(*argv,"-no_record_splitting") == 0)
+			no_record_splitting=1;
 		else if (strcmp(*argv,"-serverpref") == 0)
 			off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
 		else if (strcmp(*argv,"-legacy_renegotiation") == 0)
@@ -1189,14 +1193,16 @@
 		}
 #endif
 
-	/* Enable handshake cutthrough for client connections using
-	 * strong ciphers. */
+	ssl_mode = SSL_CTX_get_mode(ctx);
+	if (!no_record_splitting)
+		ssl_mode |= SSL_MODE_CBC_RECORD_SPLITTING;
 	if (cutthrough)
 		{
-		int ssl_mode = SSL_CTX_get_mode(ctx);
+		/* Enable handshake cutthrough for client connections using
+		 * strong ciphers. */
 		ssl_mode |= SSL_MODE_HANDSHAKE_CUTTHROUGH;
-		SSL_CTX_set_mode(ctx, ssl_mode);
 		}
+	SSL_CTX_set_mode(ctx, ssl_mode);
 
 	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
 	if (cipher != NULL)
diff --git a/build-config.mk b/build-config-32.mk
similarity index 89%
rename from build-config.mk
rename to build-config-32.mk
index 18e6a86..b62c342 100644
--- a/build-config.mk
+++ b/build-config-32.mk
@@ -1,6 +1,6 @@
 # Auto-generated - DO NOT EDIT!
 # To regenerate, edit openssl.config, then run:
-#     ./import_openssl.sh import /path/to/openssl-1.0.1e.tar.gz
+#     ./import_openssl.sh import /path/to/openssl-1.0.1f.tar.gz
 #
 openssl_cflags := \
   -DOPENSSL_THREADS \
@@ -12,7 +12,6 @@
   -DOPENSSL_NO_CAMELLIA \
   -DOPENSSL_NO_CAPIENG \
   -DOPENSSL_NO_CAST \
-  -DOPENSSL_NO_CMS \
   -DOPENSSL_NO_DTLS1 \
   -DOPENSSL_NO_EC_NISTP_64_GCC_128 \
   -DOPENSSL_NO_GMP \
@@ -32,4 +31,3 @@
   -DOPENSSL_NO_STATIC_ENGINE \
   -DOPENSSL_NO_STORE \
   -DOPENSSL_NO_WHIRLPOOL \
-
diff --git a/build-config.mk b/build-config-64.mk
similarity index 89%
copy from build-config.mk
copy to build-config-64.mk
index 18e6a86..b62c342 100644
--- a/build-config.mk
+++ b/build-config-64.mk
@@ -1,6 +1,6 @@
 # Auto-generated - DO NOT EDIT!
 # To regenerate, edit openssl.config, then run:
-#     ./import_openssl.sh import /path/to/openssl-1.0.1e.tar.gz
+#     ./import_openssl.sh import /path/to/openssl-1.0.1f.tar.gz
 #
 openssl_cflags := \
   -DOPENSSL_THREADS \
@@ -12,7 +12,6 @@
   -DOPENSSL_NO_CAMELLIA \
   -DOPENSSL_NO_CAPIENG \
   -DOPENSSL_NO_CAST \
-  -DOPENSSL_NO_CMS \
   -DOPENSSL_NO_DTLS1 \
   -DOPENSSL_NO_EC_NISTP_64_GCC_128 \
   -DOPENSSL_NO_GMP \
@@ -32,4 +31,3 @@
   -DOPENSSL_NO_STATIC_ENGINE \
   -DOPENSSL_NO_STORE \
   -DOPENSSL_NO_WHIRLPOOL \
-
diff --git a/crypto/aes/asm/aes-parisc.pl b/crypto/aes/asm/aes-parisc.pl
index c36b6a2..714dcfb 100644
--- a/crypto/aes/asm/aes-parisc.pl
+++ b/crypto/aes/asm/aes-parisc.pl
@@ -1015,7 +1015,8 @@
 		$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/crypto/aes/asm/bsaes-x86_64.S b/crypto/aes/asm/bsaes-x86_64.S
index 6ceb3da..dc92d4d 100644
--- a/crypto/aes/asm/bsaes-x86_64.S
+++ b/crypto/aes/asm/bsaes-x86_64.S
@@ -364,7 +364,6 @@
 	pxor	%xmm11,%xmm7
 	pshufd	$78,%xmm3,%xmm1
 	pxor	%xmm12,%xmm8
-
 	pxor	%xmm10,%xmm2
 	pxor	%xmm14,%xmm6
 	pxor	%xmm13,%xmm5
@@ -797,148 +796,86 @@
 	decl	%r10d
 	jl	.Ldec_done
 
-	pshufd	$147,%xmm4,%xmm14
-	movdqa	%xmm5,%xmm9
-	pxor	%xmm6,%xmm4
-	pxor	%xmm6,%xmm5
-	pshufd	$147,%xmm15,%xmm7
-	movdqa	%xmm6,%xmm12
-	pxor	%xmm15,%xmm6
-	pxor	%xmm0,%xmm15
-	pshufd	$147,%xmm0,%xmm8
-	pxor	%xmm5,%xmm0
-	pxor	%xmm2,%xmm15
-	pxor	%xmm3,%xmm0
-	pshufd	$147,%xmm3,%xmm10
-	pxor	%xmm15,%xmm5
-	pxor	%xmm4,%xmm3
-	pxor	%xmm2,%xmm4
-	pshufd	$147,%xmm2,%xmm13
-	movdqa	%xmm1,%xmm11
-	pxor	%xmm1,%xmm2
-	pxor	%xmm3,%xmm1
-	pxor	%xmm4,%xmm3
-	pxor	%xmm12,%xmm2
-	pxor	%xmm9,%xmm3
-	pxor	%xmm11,%xmm3
-	pshufd	$147,%xmm12,%xmm12
-
-	pxor	%xmm4,%xmm6
-	pxor	%xmm7,%xmm4
-	pxor	%xmm8,%xmm6
-	pshufd	$147,%xmm9,%xmm9
-	pxor	%xmm12,%xmm4
-	pxor	%xmm13,%xmm6
-	pxor	%xmm14,%xmm4
-	pshufd	$147,%xmm11,%xmm11
-	pxor	%xmm13,%xmm14
-	pxor	%xmm4,%xmm6
-
-	pxor	%xmm7,%xmm5
-	pshufd	$147,%xmm7,%xmm7
-	pxor	%xmm8,%xmm15
-	pxor	%xmm8,%xmm0
-	pxor	%xmm9,%xmm15
-	pshufd	$147,%xmm8,%xmm8
-	pxor	%xmm9,%xmm5
-	pxor	%xmm9,%xmm3
-	pxor	%xmm14,%xmm15
-	pshufd	$147,%xmm9,%xmm9
-	pxor	%xmm10,%xmm5
-	pxor	%xmm10,%xmm1
-	pxor	%xmm10,%xmm0
-	pshufd	$147,%xmm10,%xmm10
-	pxor	%xmm11,%xmm2
-	pxor	%xmm11,%xmm3
-	pxor	%xmm14,%xmm2
-	pxor	%xmm12,%xmm5
-	pxor	%xmm11,%xmm0
-	pxor	%xmm12,%xmm14
-
-	pxor	%xmm14,%xmm3
-	pshufd	$147,%xmm11,%xmm11
-	pxor	%xmm14,%xmm1
-	pxor	%xmm14,%xmm0
-
-	pxor	%xmm12,%xmm14
-	pshufd	$147,%xmm12,%xmm12
-	pxor	%xmm13,%xmm14
-
-
-	pxor	%xmm2,%xmm0
-	pxor	%xmm11,%xmm2
-	pshufd	$147,%xmm13,%xmm13
-	pxor	%xmm7,%xmm15
-	pxor	%xmm12,%xmm2
-	pxor	%xmm9,%xmm15
-	pshufd	$147,%xmm14,%xmm14
-
-	pxor	%xmm6,%xmm5
-	pxor	%xmm8,%xmm6
-	pxor	%xmm7,%xmm4
-	pxor	%xmm7,%xmm5
-	pxor	%xmm12,%xmm6
-	pxor	%xmm12,%xmm4
-	pxor	%xmm14,%xmm6
-	pshufd	$147,%xmm7,%xmm7
-	pxor	%xmm13,%xmm4
-	pxor	%xmm6,%xmm5
-	pxor	%xmm8,%xmm0
-	pshufd	$147,%xmm8,%xmm8
-
-	pxor	%xmm14,%xmm2
-	pxor	%xmm9,%xmm0
-	pxor	%xmm9,%xmm3
-	pshufd	$147,%xmm9,%xmm9
+	pshufd	$78,%xmm15,%xmm7
+	pshufd	$78,%xmm2,%xmm13
+	pxor	%xmm15,%xmm7
+	pshufd	$78,%xmm4,%xmm14
+	pxor	%xmm2,%xmm13
+	pshufd	$78,%xmm0,%xmm8
+	pxor	%xmm4,%xmm14
+	pshufd	$78,%xmm5,%xmm9
+	pxor	%xmm0,%xmm8
+	pshufd	$78,%xmm3,%xmm10
+	pxor	%xmm5,%xmm9
 	pxor	%xmm13,%xmm15
-	pxor	%xmm10,%xmm13
-	pxor	%xmm2,%xmm0
-	pxor	%xmm13,%xmm5
-
-	pxor	%xmm13,%xmm1
-	pxor	%xmm12,%xmm3
-	pxor	%xmm11,%xmm1
-	pshufd	$147,%xmm11,%xmm11
-	pxor	%xmm13,%xmm3
-	pxor	%xmm14,%xmm1
-	pxor	%xmm10,%xmm13
-
-	pshufd	$147,%xmm12,%xmm12
-	pshufd	$147,%xmm13,%xmm13
-	pshufd	$147,%xmm14,%xmm14
-	pshufd	$147,%xmm10,%xmm10
-
-
-	pxor	%xmm6,%xmm0
-	pxor	%xmm6,%xmm8
-	pxor	%xmm12,%xmm7
-	pxor	%xmm12,%xmm8
+	pxor	%xmm13,%xmm0
+	pshufd	$78,%xmm1,%xmm11
+	pxor	%xmm3,%xmm10
 	pxor	%xmm7,%xmm5
-	pxor	%xmm4,%xmm7
-	pxor	%xmm13,%xmm8
-	pxor	%xmm14,%xmm13
-	pxor	%xmm8,%xmm0
-	pxor	%xmm11,%xmm2
-	pxor	%xmm0,%xmm11
-	pxor	%xmm10,%xmm1
-	pxor	%xmm5,%xmm10
-	pxor	%xmm9,%xmm3
-	pxor	%xmm15,%xmm9
-	pxor	%xmm14,%xmm10
-	pxor	%xmm3,%xmm12
-	pxor	%xmm13,%xmm9
-	pxor	%xmm13,%xmm12
-	pxor	%xmm1,%xmm13
-	pxor	%xmm2,%xmm14
+	pxor	%xmm8,%xmm3
+	pshufd	$78,%xmm6,%xmm12
+	pxor	%xmm1,%xmm11
+	pxor	%xmm14,%xmm0
+	pxor	%xmm9,%xmm1
+	pxor	%xmm6,%xmm12
 
-	movdqa	%xmm7,%xmm15
-	movdqa	%xmm8,%xmm0
-	movdqa	%xmm9,%xmm1
-	movdqa	%xmm10,%xmm2
-	movdqa	%xmm11,%xmm3
-	movdqa	%xmm12,%xmm4
+	pxor	%xmm14,%xmm5
+	pxor	%xmm13,%xmm3
+	pxor	%xmm13,%xmm1
+	pxor	%xmm10,%xmm6
+	pxor	%xmm11,%xmm2
+	pxor	%xmm14,%xmm1
+	pxor	%xmm14,%xmm6
+	pxor	%xmm12,%xmm4
+	pshufd	$147,%xmm15,%xmm7
+	pshufd	$147,%xmm0,%xmm8
+	pxor	%xmm7,%xmm15
+	pshufd	$147,%xmm5,%xmm9
+	pxor	%xmm8,%xmm0
+	pshufd	$147,%xmm3,%xmm10
+	pxor	%xmm9,%xmm5
+	pshufd	$147,%xmm1,%xmm11
+	pxor	%xmm10,%xmm3
+	pshufd	$147,%xmm6,%xmm12
+	pxor	%xmm11,%xmm1
+	pshufd	$147,%xmm2,%xmm13
+	pxor	%xmm12,%xmm6
+	pshufd	$147,%xmm4,%xmm14
+	pxor	%xmm13,%xmm2
+	pxor	%xmm14,%xmm4
+
+	pxor	%xmm15,%xmm8
+	pxor	%xmm4,%xmm7
+	pxor	%xmm4,%xmm8
+	pshufd	$78,%xmm15,%xmm15
+	pxor	%xmm0,%xmm9
+	pshufd	$78,%xmm0,%xmm0
+	pxor	%xmm1,%xmm12
+	pxor	%xmm7,%xmm15
+	pxor	%xmm6,%xmm13
+	pxor	%xmm8,%xmm0
+	pxor	%xmm3,%xmm11
+	pshufd	$78,%xmm1,%xmm7
+	pxor	%xmm2,%xmm14
+	pshufd	$78,%xmm6,%xmm8
+	pxor	%xmm5,%xmm10
+	pshufd	$78,%xmm3,%xmm1
+	pxor	%xmm4,%xmm10
+	pshufd	$78,%xmm4,%xmm6
+	pxor	%xmm4,%xmm11
+	pshufd	$78,%xmm2,%xmm3
+	pxor	%xmm11,%xmm7
+	pshufd	$78,%xmm5,%xmm2
+	pxor	%xmm12,%xmm8
+	pxor	%xmm1,%xmm10
+	pxor	%xmm14,%xmm6
+	pxor	%xmm3,%xmm13
+	movdqa	%xmm7,%xmm3
+	pxor	%xmm9,%xmm2
 	movdqa	%xmm13,%xmm5
-	movdqa	%xmm14,%xmm6
+	movdqa	%xmm8,%xmm4
+	movdqa	%xmm2,%xmm1
+	movdqa	%xmm10,%xmm2
 	movdqa	-16(%r11),%xmm7
 	jnz	.Ldec_loop
 	movdqa	-32(%r11),%xmm7
diff --git a/crypto/aes/asm/bsaes-x86_64.pl b/crypto/aes/asm/bsaes-x86_64.pl
index ceb02b5..41b90f0 100644
--- a/crypto/aes/asm/bsaes-x86_64.pl
+++ b/crypto/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.
 #
@@ -456,6 +456,7 @@
 # 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]
@@ -497,7 +498,8 @@
 	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]
@@ -505,9 +507,20 @@
 	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];
 
@@ -661,6 +674,54 @@
 ___
 }
 
+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];
@@ -2028,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/crypto/asn1/a_int.c b/crypto/asn1/a_int.c
index ad0d250..297c45a 100644
--- a/crypto/asn1/a_int.c
+++ b/crypto/asn1/a_int.c
@@ -116,7 +116,7 @@
 	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/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c
index 8990909..54c012c 100644
--- a/crypto/bio/bss_dgram.c
+++ b/crypto/bio/bss_dgram.c
@@ -906,8 +906,8 @@
 	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))
 		{
@@ -1197,7 +1197,7 @@
 			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))
 				{
diff --git a/crypto/bn/asm/bn-mips.S b/crypto/bn/asm/bn-mips.S
index 229c709..2e7cccb 100644
--- a/crypto/bn/asm/bn-mips.S
+++ b/crypto/bn/asm/bn-mips.S
@@ -23,10 +23,10 @@
 	.set	reorder
 	li	$3,-4
 	and	$8,$6,$3
-	lw	$12,0($5)
 	beqz	$8,.L_bn_mul_add_words_tail
 
 .L_bn_mul_add_words_loop:
+	lw	$12,0($5)
 	multu	$12,$7
 	lw	$13,0($4)
 	lw	$14,4($5)
@@ -83,10 +83,9 @@
 	addu	$2,$10
 	sltu	$1,$11,$1
 	sw	$11,-4($4)
-	addu	$2,$1
 	.set	noreorder
-	bgtzl	$8,.L_bn_mul_add_words_loop
-	lw	$12,0($5)
+	bgtz	$8,.L_bn_mul_add_words_loop
+	addu	$2,$1
 
 	beqz	$6,.L_bn_mul_add_words_return
 	nop
@@ -159,10 +158,10 @@
 	.set	reorder
 	li	$3,-4
 	and	$8,$6,$3
-	lw	$12,0($5)
 	beqz	$8,.L_bn_mul_words_tail
 
 .L_bn_mul_words_loop:
+	lw	$12,0($5)
 	multu	$12,$7
 	lw	$14,4($5)
 	lw	$8,2*4($5)
@@ -200,10 +199,9 @@
 	addu	$2,$1
 	sltu	$11,$2,$1
 	sw	$2,-4($4)
-	addu	$2,$11,$10
 	.set	noreorder
-	bgtzl	$8,.L_bn_mul_words_loop
-	lw	$12,0($5)
+	bgtz	$8,.L_bn_mul_words_loop
+	addu	$2,$11,$10
 
 	beqz	$6,.L_bn_mul_words_return
 	nop
@@ -264,10 +262,10 @@
 	.set	reorder
 	li	$3,-4
 	and	$8,$6,$3
-	lw	$12,0($5)
 	beqz	$8,.L_bn_sqr_words_tail
 
 .L_bn_sqr_words_loop:
+	lw	$12,0($5)
 	multu	$12,$12
 	lw	$14,4($5)
 	lw	$8,2*4($5)
@@ -298,11 +296,10 @@
 	mflo	$11
 	mfhi	$10
 	sw	$11,-2*4($4)
-	sw	$10,-4($4)
 
 	.set	noreorder
-	bgtzl	$8,.L_bn_sqr_words_loop
-	lw	$12,0($5)
+	bgtz	$8,.L_bn_sqr_words_loop
+	sw	$10,-4($4)
 
 	beqz	$6,.L_bn_sqr_words_return
 	nop
@@ -358,10 +355,10 @@
 	.set	reorder
 	li	$3,-4
 	and	$1,$7,$3
-	lw	$12,0($5)
 	beqz	$1,.L_bn_add_words_tail
 
 .L_bn_add_words_loop:
+	lw	$12,0($5)
 	lw	$8,0($6)
 	subu	$7,4
 	lw	$13,4($5)
@@ -400,11 +397,10 @@
 	addu	$15,$11,$2
 	sltu	$2,$15,$11
 	sw	$15,-4($4)
-	addu	$2,$25
 	
 	.set	noreorder
-	bgtzl	$1,.L_bn_add_words_loop
-	lw	$12,0($5)
+	bgtz	$1,.L_bn_add_words_loop
+	addu	$2,$25
 
 	beqz	$7,.L_bn_add_words_return
 	nop
@@ -466,10 +462,10 @@
 	.set	reorder
 	li	$3,-4
 	and	$1,$7,$3
-	lw	$12,0($5)
 	beqz	$1,.L_bn_sub_words_tail
 
 .L_bn_sub_words_loop:
+	lw	$12,0($5)
 	lw	$8,0($6)
 	subu	$7,4
 	lw	$13,4($5)
@@ -509,11 +505,10 @@
 	subu	$15,$11,$2
 	sgtu	$2,$15,$11
 	sw	$15,-4($4)
-	addu	$2,$25
 
 	.set	noreorder
-	bgtzl	$1,.L_bn_sub_words_loop
-	lw	$12,0($5)
+	bgtz	$1,.L_bn_sub_words_loop
+	addu	$2,$25
 
 	beqz	$7,.L_bn_sub_words_return
 	nop
@@ -603,8 +598,9 @@
 	sltu	$8,$5,$6
 	or	$24,$8
 	.set	noreorder
-	beqzl	$1,.L_bn_div_3_words_inner_loop
+	beqz	$1,.L_bn_div_3_words_inner_loop
 	subu	$2,1
+	addu	$2,1
 	.set	reorder
 .L_bn_div_3_words_inner_loop_done:
 	.set	noreorder
@@ -641,7 +637,8 @@
 	and	$14,$4
 	srl	$1,$5,$13
 	.set	noreorder
-	bnezl	$14,.+8
+	beqz	$14,.+12
+	nop
 	break	6		# signal overflow
 	.set	reorder
 	sll	$4,$25
@@ -651,7 +648,8 @@
 	srl	$3,$6,4*4	# bits
 	sgeu	$1,$4,$6
 	.set	noreorder
-	bnezl	$1,.+8
+	beqz	$1,.+12
+	nop
 	subu	$4,$6
 	.set	reorder
 
diff --git a/crypto/bn/asm/mips-mont.S b/crypto/bn/asm/mips-mont.S
index 32ecee5..1b875a2 100644
--- a/crypto/bn/asm/mips-mont.S
+++ b/crypto/bn/asm/mips-mont.S
@@ -13,7 +13,7 @@
 	bnez	$1,1f
 	li	$2,0
 	slt	$1,$9,17	# on in-order CPU
-	bnezl	$1,bn_mul_mont_internal
+	bnez	$1,bn_mul_mont_internal
 	nop
 1:	jr	$31
 	li	$4,0
diff --git a/crypto/bn/asm/mips-mont.pl b/crypto/bn/asm/mips-mont.pl
index b944a12..caae04e 100644
--- a/crypto/bn/asm/mips-mont.pl
+++ b/crypto/bn/asm/mips-mont.pl
@@ -133,7 +133,7 @@
 	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/crypto/bn/asm/mips.pl b/crypto/bn/asm/mips.pl
index 38b5164..d2f3ef7 100644
--- a/crypto/bn/asm/mips.pl
+++ b/crypto/bn/asm/mips.pl
@@ -140,10 +140,10 @@
 	.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 @@
 	$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 @@
 	.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 @@
 	$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 @@
 	.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 @@
 	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 @@
 	.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 @@
 	$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 @@
 	.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 @@
 	$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
@@ -840,8 +835,9 @@
 	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 @@
 	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 @@
 	$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/crypto/bn/asm/parisc-mont.pl b/crypto/bn/asm/parisc-mont.pl
index 4a766a8..c02ef6f 100644
--- a/crypto/bn/asm/parisc-mont.pl
+++ b/crypto/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 @@
 	# 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/crypto/bn/asm/x86_64-gf2m.pl b/crypto/bn/asm/x86_64-gf2m.pl
index cf9f48e..42bbec2 100644
--- a/crypto/bn/asm/x86_64-gf2m.pl
+++ b/crypto/bn/asm/x86_64-gf2m.pl
@@ -31,7 +31,8 @@
 ( $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/crypto/bn/asm/x86_64-mont5.pl b/crypto/bn/asm/x86_64-mont5.pl
index 8f8dc5a..dae0fe2 100755
--- a/crypto/bn/asm/x86_64-mont5.pl
+++ b/crypto/bn/asm/x86_64-mont5.pl
@@ -901,8 +901,8 @@
 	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/crypto/bn/bn_nist.c b/crypto/bn/bn_nist.c
index 43caee4..e22968d 100644
--- a/crypto/bn/bn_nist.c
+++ b/crypto/bn/bn_nist.c
@@ -286,26 +286,25 @@
 	}
 
 
-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 @@
 	 */
 	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	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 @@
 	/* 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 @@
 	{
 	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 @@
 	/* 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 @@
 
 	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 @@
 
 	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 @@
 
 	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/crypto/buffer/buffer.c b/crypto/buffer/buffer.c
index d7aa79a..d4a4ce4 100644
--- a/crypto/buffer/buffer.c
+++ b/crypto/buffer/buffer.c
@@ -179,14 +179,14 @@
 	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/crypto/buffer/buffer.h b/crypto/buffer/buffer.h
index 178e418..f8da32b 100644
--- a/crypto/buffer/buffer.h
+++ b/crypto/buffer/buffer.h
@@ -88,7 +88,7 @@
 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/crypto/cms/cms.h b/crypto/cms/cms.h
new file mode 100644
index 0000000..36994fa
--- /dev/null
+++ b/crypto/cms/cms.h
@@ -0,0 +1,501 @@
+/* crypto/cms/cms.h */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+
+#ifndef HEADER_CMS_H
+#define HEADER_CMS_H
+
+#include <openssl/x509.h>
+
+#ifdef OPENSSL_NO_CMS
+#error CMS is disabled.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct CMS_ContentInfo_st CMS_ContentInfo;
+typedef struct CMS_SignerInfo_st CMS_SignerInfo;
+typedef struct CMS_CertificateChoices CMS_CertificateChoices;
+typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice;
+typedef struct CMS_RecipientInfo_st CMS_RecipientInfo;
+typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest;
+typedef struct CMS_Receipt_st CMS_Receipt;
+
+DECLARE_STACK_OF(CMS_SignerInfo)
+DECLARE_STACK_OF(GENERAL_NAMES)
+DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
+DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest)
+DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
+
+#define CMS_SIGNERINFO_ISSUER_SERIAL	0
+#define CMS_SIGNERINFO_KEYIDENTIFIER	1
+
+#define CMS_RECIPINFO_TRANS		0
+#define CMS_RECIPINFO_AGREE		1
+#define CMS_RECIPINFO_KEK		2
+#define CMS_RECIPINFO_PASS		3
+#define CMS_RECIPINFO_OTHER		4
+
+/* S/MIME related flags */
+
+#define CMS_TEXT			0x1
+#define CMS_NOCERTS			0x2
+#define CMS_NO_CONTENT_VERIFY		0x4
+#define CMS_NO_ATTR_VERIFY		0x8
+#define CMS_NOSIGS			\
+			(CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY)
+#define CMS_NOINTERN			0x10
+#define CMS_NO_SIGNER_CERT_VERIFY	0x20
+#define CMS_NOVERIFY			0x20
+#define CMS_DETACHED			0x40
+#define CMS_BINARY			0x80
+#define CMS_NOATTR			0x100
+#define	CMS_NOSMIMECAP			0x200
+#define CMS_NOOLDMIMETYPE		0x400
+#define CMS_CRLFEOL			0x800
+#define CMS_STREAM			0x1000
+#define CMS_NOCRL			0x2000
+#define CMS_PARTIAL			0x4000
+#define CMS_REUSE_DIGEST		0x8000
+#define CMS_USE_KEYID			0x10000
+#define CMS_DEBUG_DECRYPT		0x20000
+
+const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms);
+
+BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont);
+int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio);
+
+ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms);
+int CMS_is_detached(CMS_ContentInfo *cms);
+int CMS_set_detached(CMS_ContentInfo *cms, int detached);
+
+#ifdef HEADER_PEM_H
+DECLARE_PEM_rw_const(CMS, CMS_ContentInfo)
+#endif
+
+int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms);
+CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms);
+int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms);
+
+BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms);
+int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags);
+int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags);
+CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont);
+int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags);
+
+int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags);
+
+CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
+						BIO *data, unsigned int flags);
+
+CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
+					X509 *signcert, EVP_PKEY *pkey,
+					STACK_OF(X509) *certs,
+					unsigned int flags);
+
+int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags);
+CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags);
+
+int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+							unsigned int flags);
+CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
+							unsigned int flags);
+
+int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
+				const unsigned char *key, size_t keylen,
+				BIO *dcont, BIO *out, unsigned int flags);
+
+CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
+					const unsigned char *key, size_t keylen,
+					unsigned int flags);
+
+int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
+				const unsigned char *key, size_t keylen);
+
+int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
+		 X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags);
+
+int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
+			STACK_OF(X509) *certs,
+			X509_STORE *store, unsigned int flags);
+
+STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
+
+CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
+				const EVP_CIPHER *cipher, unsigned int flags);
+
+int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert,
+				BIO *dcont, BIO *out,
+				unsigned int flags);
+	
+int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert);
+int CMS_decrypt_set1_key(CMS_ContentInfo *cms, 
+				unsigned char *key, size_t keylen,
+				unsigned char *id, size_t idlen);
+int CMS_decrypt_set1_password(CMS_ContentInfo *cms, 
+				unsigned char *pass, ossl_ssize_t passlen);
+
+STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
+int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
+CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
+CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
+					X509 *recip, unsigned int flags);
+int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey);
+int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert);
+int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
+					EVP_PKEY **pk, X509 **recip,
+					X509_ALGOR **palg);
+int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
+					ASN1_OCTET_STRING **keyid,
+					X509_NAME **issuer, ASN1_INTEGER **sno);
+
+CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
+					unsigned char *key, size_t keylen,
+					unsigned char *id, size_t idlen,
+					ASN1_GENERALIZEDTIME *date,
+					ASN1_OBJECT *otherTypeId,
+					ASN1_TYPE *otherType);
+
+int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
+					X509_ALGOR **palg,
+					ASN1_OCTET_STRING **pid,
+					ASN1_GENERALIZEDTIME **pdate,
+					ASN1_OBJECT **potherid,
+					ASN1_TYPE **pothertype);
+
+int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, 
+				unsigned char *key, size_t keylen);
+
+int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, 
+					const unsigned char *id, size_t idlen);
+
+int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, 
+					unsigned char *pass,
+					ossl_ssize_t passlen);
+
+CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
+					int iter, int wrap_nid, int pbe_nid,
+					unsigned char *pass,
+					ossl_ssize_t passlen,
+					const EVP_CIPHER *kekciph);
+
+int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
+	
+int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+							unsigned int flags);
+CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags);
+
+int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid);
+const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms);
+
+CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms);
+int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert);
+int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert);
+STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms);
+
+CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms);
+int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl);
+int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl);
+STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms);
+
+int CMS_SignedData_init(CMS_ContentInfo *cms);
+CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
+			X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
+			unsigned int flags);
+STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms);
+
+void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer);
+int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
+					ASN1_OCTET_STRING **keyid,
+					X509_NAME **issuer, ASN1_INTEGER **sno);
+int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert);
+int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
+					unsigned int flags);
+void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer,
+					X509_ALGOR **pdig, X509_ALGOR **psig);
+int CMS_SignerInfo_sign(CMS_SignerInfo *si);
+int CMS_SignerInfo_verify(CMS_SignerInfo *si);
+int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain);
+
+int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs);
+int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
+				int algnid, int keysize);
+int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap);
+
+int CMS_signed_get_attr_count(const CMS_SignerInfo *si);
+int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+			  int lastpos);
+int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
+			  int lastpos);
+X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc);
+X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc);
+int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
+int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
+			const ASN1_OBJECT *obj, int type,
+			const void *bytes, int len);
+int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
+			int nid, int type,
+			const void *bytes, int len);
+int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
+			const char *attrname, int type,
+			const void *bytes, int len);
+void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
+					int lastpos, int type);
+
+int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si);
+int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+			  int lastpos);
+int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
+			  int lastpos);
+X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc);
+X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc);
+int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
+int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
+			const ASN1_OBJECT *obj, int type,
+			const void *bytes, int len);
+int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
+			int nid, int type,
+			const void *bytes, int len);
+int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
+			const char *attrname, int type,
+			const void *bytes, int len);
+void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
+					int lastpos, int type);
+
+#ifdef HEADER_X509V3_H
+
+int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr);
+CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
+				int allorfirst,
+				STACK_OF(GENERAL_NAMES) *receiptList,
+				STACK_OF(GENERAL_NAMES) *receiptsTo);
+int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr);
+void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
+					ASN1_STRING **pcid,
+					int *pallorfirst,
+					STACK_OF(GENERAL_NAMES) **plist,
+					STACK_OF(GENERAL_NAMES) **prto);
+
+#endif
+
+/* 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.
+ */
+void ERR_load_CMS_strings(void);
+
+/* Error codes for the CMS functions. */
+
+/* Function codes. */
+#define CMS_F_CHECK_CONTENT				 99
+#define CMS_F_CMS_ADD0_CERT				 164
+#define CMS_F_CMS_ADD0_RECIPIENT_KEY			 100
+#define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD		 165
+#define CMS_F_CMS_ADD1_RECEIPTREQUEST			 158
+#define CMS_F_CMS_ADD1_RECIPIENT_CERT			 101
+#define CMS_F_CMS_ADD1_SIGNER				 102
+#define CMS_F_CMS_ADD1_SIGNINGTIME			 103
+#define CMS_F_CMS_COMPRESS				 104
+#define CMS_F_CMS_COMPRESSEDDATA_CREATE			 105
+#define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO		 106
+#define CMS_F_CMS_COPY_CONTENT				 107
+#define CMS_F_CMS_COPY_MESSAGEDIGEST			 108
+#define CMS_F_CMS_DATA					 109
+#define CMS_F_CMS_DATAFINAL				 110
+#define CMS_F_CMS_DATAINIT				 111
+#define CMS_F_CMS_DECRYPT				 112
+#define CMS_F_CMS_DECRYPT_SET1_KEY			 113
+#define CMS_F_CMS_DECRYPT_SET1_PASSWORD			 166
+#define CMS_F_CMS_DECRYPT_SET1_PKEY			 114
+#define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX		 115
+#define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO		 116
+#define CMS_F_CMS_DIGESTEDDATA_DO_FINAL			 117
+#define CMS_F_CMS_DIGEST_VERIFY				 118
+#define CMS_F_CMS_ENCODE_RECEIPT			 161
+#define CMS_F_CMS_ENCRYPT				 119
+#define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO		 120
+#define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT			 121
+#define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT			 122
+#define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY		 123
+#define CMS_F_CMS_ENVELOPEDDATA_CREATE			 124
+#define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO		 125
+#define CMS_F_CMS_ENVELOPED_DATA_INIT			 126
+#define CMS_F_CMS_FINAL					 127
+#define CMS_F_CMS_GET0_CERTIFICATE_CHOICES		 128
+#define CMS_F_CMS_GET0_CONTENT				 129
+#define CMS_F_CMS_GET0_ECONTENT_TYPE			 130
+#define CMS_F_CMS_GET0_ENVELOPED			 131
+#define CMS_F_CMS_GET0_REVOCATION_CHOICES		 132
+#define CMS_F_CMS_GET0_SIGNED				 133
+#define CMS_F_CMS_MSGSIGDIGEST_ADD1			 162
+#define CMS_F_CMS_RECEIPTREQUEST_CREATE0		 159
+#define CMS_F_CMS_RECEIPT_VERIFY			 160
+#define CMS_F_CMS_RECIPIENTINFO_DECRYPT			 134
+#define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT		 135
+#define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT		 136
+#define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID		 137
+#define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP		 138
+#define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP		 139
+#define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT		 140
+#define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT		 141
+#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS		 142
+#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID	 143
+#define CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT		 167
+#define CMS_F_CMS_RECIPIENTINFO_SET0_KEY		 144
+#define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD		 168
+#define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY		 145
+#define CMS_F_CMS_SET1_SIGNERIDENTIFIER			 146
+#define CMS_F_CMS_SET_DETACHED				 147
+#define CMS_F_CMS_SIGN					 148
+#define CMS_F_CMS_SIGNED_DATA_INIT			 149
+#define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN		 150
+#define CMS_F_CMS_SIGNERINFO_SIGN			 151
+#define CMS_F_CMS_SIGNERINFO_VERIFY			 152
+#define CMS_F_CMS_SIGNERINFO_VERIFY_CERT		 153
+#define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT		 154
+#define CMS_F_CMS_SIGN_RECEIPT				 163
+#define CMS_F_CMS_STREAM				 155
+#define CMS_F_CMS_UNCOMPRESS				 156
+#define CMS_F_CMS_VERIFY				 157
+
+/* Reason codes. */
+#define CMS_R_ADD_SIGNER_ERROR				 99
+#define CMS_R_CERTIFICATE_ALREADY_PRESENT		 175
+#define CMS_R_CERTIFICATE_HAS_NO_KEYID			 160
+#define CMS_R_CERTIFICATE_VERIFY_ERROR			 100
+#define CMS_R_CIPHER_INITIALISATION_ERROR		 101
+#define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR	 102
+#define CMS_R_CMS_DATAFINAL_ERROR			 103
+#define CMS_R_CMS_LIB					 104
+#define CMS_R_CONTENTIDENTIFIER_MISMATCH		 170
+#define CMS_R_CONTENT_NOT_FOUND				 105
+#define CMS_R_CONTENT_TYPE_MISMATCH			 171
+#define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA		 106
+#define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA		 107
+#define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA		 108
+#define CMS_R_CONTENT_VERIFY_ERROR			 109
+#define CMS_R_CTRL_ERROR				 110
+#define CMS_R_CTRL_FAILURE				 111
+#define CMS_R_DECRYPT_ERROR				 112
+#define CMS_R_DIGEST_ERROR				 161
+#define CMS_R_ERROR_GETTING_PUBLIC_KEY			 113
+#define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE	 114
+#define CMS_R_ERROR_SETTING_KEY				 115
+#define CMS_R_ERROR_SETTING_RECIPIENTINFO		 116
+#define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH		 117
+#define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER		 176
+#define CMS_R_INVALID_KEY_LENGTH			 118
+#define CMS_R_MD_BIO_INIT_ERROR				 119
+#define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH	 120
+#define CMS_R_MESSAGEDIGEST_WRONG_LENGTH		 121
+#define CMS_R_MSGSIGDIGEST_ERROR			 172
+#define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE		 162
+#define CMS_R_MSGSIGDIGEST_WRONG_LENGTH			 163
+#define CMS_R_NEED_ONE_SIGNER				 164
+#define CMS_R_NOT_A_SIGNED_RECEIPT			 165
+#define CMS_R_NOT_ENCRYPTED_DATA			 122
+#define CMS_R_NOT_KEK					 123
+#define CMS_R_NOT_KEY_TRANSPORT				 124
+#define CMS_R_NOT_PWRI					 177
+#define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE		 125
+#define CMS_R_NO_CIPHER					 126
+#define CMS_R_NO_CONTENT				 127
+#define CMS_R_NO_CONTENT_TYPE				 173
+#define CMS_R_NO_DEFAULT_DIGEST				 128
+#define CMS_R_NO_DIGEST_SET				 129
+#define CMS_R_NO_KEY					 130
+#define CMS_R_NO_KEY_OR_CERT				 174
+#define CMS_R_NO_MATCHING_DIGEST			 131
+#define CMS_R_NO_MATCHING_RECIPIENT			 132
+#define CMS_R_NO_MATCHING_SIGNATURE			 166
+#define CMS_R_NO_MSGSIGDIGEST				 167
+#define CMS_R_NO_PASSWORD				 178
+#define CMS_R_NO_PRIVATE_KEY				 133
+#define CMS_R_NO_PUBLIC_KEY				 134
+#define CMS_R_NO_RECEIPT_REQUEST			 168
+#define CMS_R_NO_SIGNERS				 135
+#define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE	 136
+#define CMS_R_RECEIPT_DECODE_ERROR			 169
+#define CMS_R_RECIPIENT_ERROR				 137
+#define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND		 138
+#define CMS_R_SIGNFINAL_ERROR				 139
+#define CMS_R_SMIME_TEXT_ERROR				 140
+#define CMS_R_STORE_INIT_ERROR				 141
+#define CMS_R_TYPE_NOT_COMPRESSED_DATA			 142
+#define CMS_R_TYPE_NOT_DATA				 143
+#define CMS_R_TYPE_NOT_DIGESTED_DATA			 144
+#define CMS_R_TYPE_NOT_ENCRYPTED_DATA			 145
+#define CMS_R_TYPE_NOT_ENVELOPED_DATA			 146
+#define CMS_R_UNABLE_TO_FINALIZE_CONTEXT		 147
+#define CMS_R_UNKNOWN_CIPHER				 148
+#define CMS_R_UNKNOWN_DIGEST_ALGORIHM			 149
+#define CMS_R_UNKNOWN_ID				 150
+#define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM		 151
+#define CMS_R_UNSUPPORTED_CONTENT_TYPE			 152
+#define CMS_R_UNSUPPORTED_KEK_ALGORITHM			 153
+#define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM	 179
+#define CMS_R_UNSUPPORTED_RECIPIENT_TYPE		 154
+#define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE		 155
+#define CMS_R_UNSUPPORTED_TYPE				 156
+#define CMS_R_UNWRAP_ERROR				 157
+#define CMS_R_UNWRAP_FAILURE				 180
+#define CMS_R_VERIFICATION_FAILURE			 158
+#define CMS_R_WRAP_ERROR				 159
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/crypto/cms/cms_asn1.c b/crypto/cms/cms_asn1.c
new file mode 100644
index 0000000..cfe67fb
--- /dev/null
+++ b/crypto/cms/cms_asn1.c
@@ -0,0 +1,389 @@
+/* crypto/cms/cms_asn1.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include "cms.h"
+#include "cms_lcl.h"
+
+
+ASN1_SEQUENCE(CMS_IssuerAndSerialNumber) = {
+	ASN1_SIMPLE(CMS_IssuerAndSerialNumber, issuer, X509_NAME),
+	ASN1_SIMPLE(CMS_IssuerAndSerialNumber, serialNumber, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(CMS_IssuerAndSerialNumber)
+
+ASN1_SEQUENCE(CMS_OtherCertificateFormat) = {
+	ASN1_SIMPLE(CMS_OtherCertificateFormat, otherCertFormat, ASN1_OBJECT),
+	ASN1_OPT(CMS_OtherCertificateFormat, otherCert, ASN1_ANY)
+} ASN1_SEQUENCE_END(CMS_OtherCertificateFormat)
+
+ASN1_CHOICE(CMS_CertificateChoices) = {
+	ASN1_SIMPLE(CMS_CertificateChoices, d.certificate, X509),
+	ASN1_IMP(CMS_CertificateChoices, d.extendedCertificate, ASN1_SEQUENCE, 0),
+	ASN1_IMP(CMS_CertificateChoices, d.v1AttrCert, ASN1_SEQUENCE, 1),
+	ASN1_IMP(CMS_CertificateChoices, d.v2AttrCert, ASN1_SEQUENCE, 2),
+	ASN1_IMP(CMS_CertificateChoices, d.other, CMS_OtherCertificateFormat, 3)
+} ASN1_CHOICE_END(CMS_CertificateChoices)
+
+ASN1_CHOICE(CMS_SignerIdentifier) = {
+	ASN1_SIMPLE(CMS_SignerIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
+	ASN1_IMP(CMS_SignerIdentifier, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0)
+} ASN1_CHOICE_END(CMS_SignerIdentifier)
+
+ASN1_NDEF_SEQUENCE(CMS_EncapsulatedContentInfo) = {
+	ASN1_SIMPLE(CMS_EncapsulatedContentInfo, eContentType, ASN1_OBJECT),
+	ASN1_NDEF_EXP_OPT(CMS_EncapsulatedContentInfo, eContent, ASN1_OCTET_STRING_NDEF, 0)
+} ASN1_NDEF_SEQUENCE_END(CMS_EncapsulatedContentInfo)
+
+/* Minor tweak to operation: free up signer key, cert */
+static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+							void *exarg)
+	{
+	if(operation == ASN1_OP_FREE_POST)
+		{
+		CMS_SignerInfo *si = (CMS_SignerInfo *)*pval;
+		if (si->pkey)
+			EVP_PKEY_free(si->pkey);
+		if (si->signer)
+			X509_free(si->signer);
+		}
+	return 1;
+	}
+
+ASN1_SEQUENCE_cb(CMS_SignerInfo, cms_si_cb) = {
+	ASN1_SIMPLE(CMS_SignerInfo, version, LONG),
+	ASN1_SIMPLE(CMS_SignerInfo, sid, CMS_SignerIdentifier),
+	ASN1_SIMPLE(CMS_SignerInfo, digestAlgorithm, X509_ALGOR),
+	ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, signedAttrs, X509_ATTRIBUTE, 0),
+	ASN1_SIMPLE(CMS_SignerInfo, signatureAlgorithm, X509_ALGOR),
+	ASN1_SIMPLE(CMS_SignerInfo, signature, ASN1_OCTET_STRING),
+	ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, unsignedAttrs, X509_ATTRIBUTE, 1)
+} ASN1_SEQUENCE_END_cb(CMS_SignerInfo, CMS_SignerInfo)
+
+ASN1_SEQUENCE(CMS_OtherRevocationInfoFormat) = {
+	ASN1_SIMPLE(CMS_OtherRevocationInfoFormat, otherRevInfoFormat, ASN1_OBJECT),
+	ASN1_OPT(CMS_OtherRevocationInfoFormat, otherRevInfo, ASN1_ANY)
+} ASN1_SEQUENCE_END(CMS_OtherRevocationInfoFormat)
+
+ASN1_CHOICE(CMS_RevocationInfoChoice) = {
+	ASN1_SIMPLE(CMS_RevocationInfoChoice, d.crl, X509_CRL),
+	ASN1_IMP(CMS_RevocationInfoChoice, d.other, CMS_OtherRevocationInfoFormat, 1)
+} ASN1_CHOICE_END(CMS_RevocationInfoChoice)
+
+ASN1_NDEF_SEQUENCE(CMS_SignedData) = {
+	ASN1_SIMPLE(CMS_SignedData, version, LONG),
+	ASN1_SET_OF(CMS_SignedData, digestAlgorithms, X509_ALGOR),
+	ASN1_SIMPLE(CMS_SignedData, encapContentInfo, CMS_EncapsulatedContentInfo),
+	ASN1_IMP_SET_OF_OPT(CMS_SignedData, certificates, CMS_CertificateChoices, 0),
+	ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1),
+	ASN1_SET_OF(CMS_SignedData, signerInfos, CMS_SignerInfo)
+} ASN1_NDEF_SEQUENCE_END(CMS_SignedData)
+
+ASN1_SEQUENCE(CMS_OriginatorInfo) = {
+	ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, certificates, CMS_CertificateChoices, 0),
+	ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, crls, CMS_RevocationInfoChoice, 1)
+} ASN1_SEQUENCE_END(CMS_OriginatorInfo)
+
+ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = {
+	ASN1_SIMPLE(CMS_EncryptedContentInfo, contentType, ASN1_OBJECT),
+	ASN1_SIMPLE(CMS_EncryptedContentInfo, contentEncryptionAlgorithm, X509_ALGOR),
+	ASN1_IMP_OPT(CMS_EncryptedContentInfo, encryptedContent, ASN1_OCTET_STRING_NDEF, 0)
+} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedContentInfo)
+
+ASN1_SEQUENCE(CMS_KeyTransRecipientInfo) = {
+	ASN1_SIMPLE(CMS_KeyTransRecipientInfo, version, LONG),
+	ASN1_SIMPLE(CMS_KeyTransRecipientInfo, rid, CMS_SignerIdentifier),
+	ASN1_SIMPLE(CMS_KeyTransRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
+	ASN1_SIMPLE(CMS_KeyTransRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(CMS_KeyTransRecipientInfo)
+
+ASN1_SEQUENCE(CMS_OtherKeyAttribute) = {
+	ASN1_SIMPLE(CMS_OtherKeyAttribute, keyAttrId, ASN1_OBJECT),
+	ASN1_OPT(CMS_OtherKeyAttribute, keyAttr, ASN1_ANY)
+} ASN1_SEQUENCE_END(CMS_OtherKeyAttribute)
+
+ASN1_SEQUENCE(CMS_RecipientKeyIdentifier) = {
+	ASN1_SIMPLE(CMS_RecipientKeyIdentifier, subjectKeyIdentifier, ASN1_OCTET_STRING),
+	ASN1_OPT(CMS_RecipientKeyIdentifier, date, ASN1_GENERALIZEDTIME),
+	ASN1_OPT(CMS_RecipientKeyIdentifier, other, CMS_OtherKeyAttribute)
+} ASN1_SEQUENCE_END(CMS_RecipientKeyIdentifier)
+
+ASN1_CHOICE(CMS_KeyAgreeRecipientIdentifier) = {
+  ASN1_SIMPLE(CMS_KeyAgreeRecipientIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
+  ASN1_IMP(CMS_KeyAgreeRecipientIdentifier, d.rKeyId, CMS_RecipientKeyIdentifier, 0)
+} ASN1_CHOICE_END(CMS_KeyAgreeRecipientIdentifier)
+
+ASN1_SEQUENCE(CMS_RecipientEncryptedKey) = {
+	ASN1_SIMPLE(CMS_RecipientEncryptedKey, rid, CMS_KeyAgreeRecipientIdentifier),
+	ASN1_SIMPLE(CMS_RecipientEncryptedKey, encryptedKey, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(CMS_RecipientEncryptedKey)
+
+ASN1_SEQUENCE(CMS_OriginatorPublicKey) = {
+  ASN1_SIMPLE(CMS_OriginatorPublicKey, algorithm, X509_ALGOR),
+  ASN1_SIMPLE(CMS_OriginatorPublicKey, publicKey, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END(CMS_OriginatorPublicKey)
+
+ASN1_CHOICE(CMS_OriginatorIdentifierOrKey) = {
+  ASN1_SIMPLE(CMS_OriginatorIdentifierOrKey, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
+  ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0),
+  ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.originatorKey, CMS_OriginatorPublicKey, 1)
+} ASN1_CHOICE_END(CMS_OriginatorIdentifierOrKey)
+
+ASN1_SEQUENCE(CMS_KeyAgreeRecipientInfo) = {
+	ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, version, LONG),
+	ASN1_EXP(CMS_KeyAgreeRecipientInfo, originator, CMS_OriginatorIdentifierOrKey, 0),
+	ASN1_EXP_OPT(CMS_KeyAgreeRecipientInfo, ukm, ASN1_OCTET_STRING, 1),
+	ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
+	ASN1_SEQUENCE_OF(CMS_KeyAgreeRecipientInfo, recipientEncryptedKeys, CMS_RecipientEncryptedKey)
+} ASN1_SEQUENCE_END(CMS_KeyAgreeRecipientInfo)
+
+ASN1_SEQUENCE(CMS_KEKIdentifier) = {
+	ASN1_SIMPLE(CMS_KEKIdentifier, keyIdentifier, ASN1_OCTET_STRING),
+	ASN1_OPT(CMS_KEKIdentifier, date, ASN1_GENERALIZEDTIME),
+	ASN1_OPT(CMS_KEKIdentifier, other, CMS_OtherKeyAttribute)
+} ASN1_SEQUENCE_END(CMS_KEKIdentifier)
+
+ASN1_SEQUENCE(CMS_KEKRecipientInfo) = {
+	ASN1_SIMPLE(CMS_KEKRecipientInfo, version, LONG),
+	ASN1_SIMPLE(CMS_KEKRecipientInfo, kekid, CMS_KEKIdentifier),
+	ASN1_SIMPLE(CMS_KEKRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
+	ASN1_SIMPLE(CMS_KEKRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(CMS_KEKRecipientInfo)
+
+ASN1_SEQUENCE(CMS_PasswordRecipientInfo) = {
+	ASN1_SIMPLE(CMS_PasswordRecipientInfo, version, LONG),
+	ASN1_IMP_OPT(CMS_PasswordRecipientInfo, keyDerivationAlgorithm, X509_ALGOR, 0),
+	ASN1_SIMPLE(CMS_PasswordRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
+	ASN1_SIMPLE(CMS_PasswordRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(CMS_PasswordRecipientInfo)
+
+ASN1_SEQUENCE(CMS_OtherRecipientInfo) = {
+  ASN1_SIMPLE(CMS_OtherRecipientInfo, oriType, ASN1_OBJECT),
+  ASN1_OPT(CMS_OtherRecipientInfo, oriValue, ASN1_ANY)
+} ASN1_SEQUENCE_END(CMS_OtherRecipientInfo)
+
+/* Free up RecipientInfo additional data */
+static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+							void *exarg)
+	{
+	if(operation == ASN1_OP_FREE_PRE)
+		{
+		CMS_RecipientInfo *ri = (CMS_RecipientInfo *)*pval;
+		if (ri->type == CMS_RECIPINFO_TRANS)
+			{
+			CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
+			if (ktri->pkey)
+				EVP_PKEY_free(ktri->pkey);
+			if (ktri->recip)
+				X509_free(ktri->recip);
+			}
+		else if (ri->type == CMS_RECIPINFO_KEK)
+			{
+			CMS_KEKRecipientInfo *kekri = ri->d.kekri;
+			if (kekri->key)
+				{
+				OPENSSL_cleanse(kekri->key, kekri->keylen);
+				OPENSSL_free(kekri->key);
+				}
+			}
+		else if (ri->type == CMS_RECIPINFO_PASS)
+			{
+			CMS_PasswordRecipientInfo *pwri = ri->d.pwri;
+			if (pwri->pass)
+				{
+				OPENSSL_cleanse(pwri->pass, pwri->passlen);
+				OPENSSL_free(pwri->pass);
+				}
+			}
+		}
+	return 1;
+	}
+
+ASN1_CHOICE_cb(CMS_RecipientInfo, cms_ri_cb) = {
+	ASN1_SIMPLE(CMS_RecipientInfo, d.ktri, CMS_KeyTransRecipientInfo),
+	ASN1_IMP(CMS_RecipientInfo, d.kari, CMS_KeyAgreeRecipientInfo, 1),
+	ASN1_IMP(CMS_RecipientInfo, d.kekri, CMS_KEKRecipientInfo, 2),
+	ASN1_IMP(CMS_RecipientInfo, d.pwri, CMS_PasswordRecipientInfo, 3),
+	ASN1_IMP(CMS_RecipientInfo, d.ori, CMS_OtherRecipientInfo, 4)
+} ASN1_CHOICE_END_cb(CMS_RecipientInfo, CMS_RecipientInfo, type)
+
+ASN1_NDEF_SEQUENCE(CMS_EnvelopedData) = {
+	ASN1_SIMPLE(CMS_EnvelopedData, version, LONG),
+	ASN1_IMP_OPT(CMS_EnvelopedData, originatorInfo, CMS_OriginatorInfo, 0),
+	ASN1_SET_OF(CMS_EnvelopedData, recipientInfos, CMS_RecipientInfo),
+	ASN1_SIMPLE(CMS_EnvelopedData, encryptedContentInfo, CMS_EncryptedContentInfo),
+	ASN1_IMP_SET_OF_OPT(CMS_EnvelopedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
+} ASN1_NDEF_SEQUENCE_END(CMS_EnvelopedData)
+
+ASN1_NDEF_SEQUENCE(CMS_DigestedData) = {
+	ASN1_SIMPLE(CMS_DigestedData, version, LONG),
+	ASN1_SIMPLE(CMS_DigestedData, digestAlgorithm, X509_ALGOR),
+	ASN1_SIMPLE(CMS_DigestedData, encapContentInfo, CMS_EncapsulatedContentInfo),
+	ASN1_SIMPLE(CMS_DigestedData, digest, ASN1_OCTET_STRING)
+} ASN1_NDEF_SEQUENCE_END(CMS_DigestedData)
+
+ASN1_NDEF_SEQUENCE(CMS_EncryptedData) = {
+	ASN1_SIMPLE(CMS_EncryptedData, version, LONG),
+	ASN1_SIMPLE(CMS_EncryptedData, encryptedContentInfo, CMS_EncryptedContentInfo),
+	ASN1_IMP_SET_OF_OPT(CMS_EncryptedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
+} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedData)
+
+ASN1_NDEF_SEQUENCE(CMS_AuthenticatedData) = {
+	ASN1_SIMPLE(CMS_AuthenticatedData, version, LONG),
+	ASN1_IMP_OPT(CMS_AuthenticatedData, originatorInfo, CMS_OriginatorInfo, 0),
+	ASN1_SET_OF(CMS_AuthenticatedData, recipientInfos, CMS_RecipientInfo),
+	ASN1_SIMPLE(CMS_AuthenticatedData, macAlgorithm, X509_ALGOR),
+	ASN1_IMP(CMS_AuthenticatedData, digestAlgorithm, X509_ALGOR, 1),
+	ASN1_SIMPLE(CMS_AuthenticatedData, encapContentInfo, CMS_EncapsulatedContentInfo),
+	ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, authAttrs, X509_ALGOR, 2),
+	ASN1_SIMPLE(CMS_AuthenticatedData, mac, ASN1_OCTET_STRING),
+	ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, unauthAttrs, X509_ALGOR, 3)
+} ASN1_NDEF_SEQUENCE_END(CMS_AuthenticatedData)
+
+ASN1_NDEF_SEQUENCE(CMS_CompressedData) = {
+	ASN1_SIMPLE(CMS_CompressedData, version, LONG),
+	ASN1_SIMPLE(CMS_CompressedData, compressionAlgorithm, X509_ALGOR),
+	ASN1_SIMPLE(CMS_CompressedData, encapContentInfo, CMS_EncapsulatedContentInfo),
+} ASN1_NDEF_SEQUENCE_END(CMS_CompressedData)
+
+/* This is the ANY DEFINED BY table for the top level ContentInfo structure */
+
+ASN1_ADB_TEMPLATE(cms_default) = ASN1_EXP(CMS_ContentInfo, d.other, ASN1_ANY, 0);
+
+ASN1_ADB(CMS_ContentInfo) = {
+	ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP(CMS_ContentInfo, d.data, ASN1_OCTET_STRING_NDEF, 0)),
+	ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP(CMS_ContentInfo, d.signedData, CMS_SignedData, 0)),
+	ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP(CMS_ContentInfo, d.envelopedData, CMS_EnvelopedData, 0)),
+	ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP(CMS_ContentInfo, d.digestedData, CMS_DigestedData, 0)),
+	ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP(CMS_ContentInfo, d.encryptedData, CMS_EncryptedData, 0)),
+	ADB_ENTRY(NID_id_smime_ct_authData, ASN1_NDEF_EXP(CMS_ContentInfo, d.authenticatedData, CMS_AuthenticatedData, 0)),
+	ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)),
+} ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL);
+
+/* CMS streaming support */
+static int cms_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+							void *exarg)
+	{
+	ASN1_STREAM_ARG *sarg = exarg;
+	CMS_ContentInfo *cms = NULL;
+	if (pval)
+		cms = (CMS_ContentInfo *)*pval;
+	else
+		return 1;
+	switch(operation)
+		{
+
+		case ASN1_OP_STREAM_PRE:
+		if (CMS_stream(&sarg->boundary, cms) <= 0)
+			return 0;
+		case ASN1_OP_DETACHED_PRE:
+		sarg->ndef_bio = CMS_dataInit(cms, sarg->out);
+		if (!sarg->ndef_bio)
+			return 0;
+		break;
+
+		case ASN1_OP_STREAM_POST:
+		case ASN1_OP_DETACHED_POST:
+		if (CMS_dataFinal(cms, sarg->ndef_bio) <= 0)
+			return 0;
+		break;
+
+		}
+	return 1;
+	}
+
+ASN1_NDEF_SEQUENCE_cb(CMS_ContentInfo, cms_cb) = {
+	ASN1_SIMPLE(CMS_ContentInfo, contentType, ASN1_OBJECT),
+	ASN1_ADB_OBJECT(CMS_ContentInfo)
+} ASN1_NDEF_SEQUENCE_END_cb(CMS_ContentInfo, CMS_ContentInfo)
+
+/* Specials for signed attributes */
+
+/* When signing attributes we want to reorder them to match the sorted
+ * encoding.
+ */
+
+ASN1_ITEM_TEMPLATE(CMS_Attributes_Sign) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, CMS_ATTRIBUTES, X509_ATTRIBUTE)
+ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Sign)
+
+/* When verifying attributes we need to use the received order. So 
+ * we use SEQUENCE OF and tag it to SET OF
+ */
+
+ASN1_ITEM_TEMPLATE(CMS_Attributes_Verify) = 
+	ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
+				V_ASN1_SET, CMS_ATTRIBUTES, X509_ATTRIBUTE)
+ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Verify)
+
+
+
+ASN1_CHOICE(CMS_ReceiptsFrom) = {
+  ASN1_IMP(CMS_ReceiptsFrom, d.allOrFirstTier, LONG, 0),
+  ASN1_IMP_SEQUENCE_OF(CMS_ReceiptsFrom, d.receiptList, GENERAL_NAMES, 1)
+} ASN1_CHOICE_END(CMS_ReceiptsFrom)
+
+ASN1_SEQUENCE(CMS_ReceiptRequest) = {
+  ASN1_SIMPLE(CMS_ReceiptRequest, signedContentIdentifier, ASN1_OCTET_STRING),
+  ASN1_SIMPLE(CMS_ReceiptRequest, receiptsFrom, CMS_ReceiptsFrom),
+  ASN1_SEQUENCE_OF(CMS_ReceiptRequest, receiptsTo, GENERAL_NAMES)
+} ASN1_SEQUENCE_END(CMS_ReceiptRequest)
+
+ASN1_SEQUENCE(CMS_Receipt) = {
+  ASN1_SIMPLE(CMS_Receipt, version, LONG),
+  ASN1_SIMPLE(CMS_Receipt, contentType, ASN1_OBJECT),
+  ASN1_SIMPLE(CMS_Receipt, signedContentIdentifier, ASN1_OCTET_STRING),
+  ASN1_SIMPLE(CMS_Receipt, originatorSignatureValue, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(CMS_Receipt)
+
diff --git a/crypto/cms/cms_att.c b/crypto/cms/cms_att.c
new file mode 100644
index 0000000..5b71722
--- /dev/null
+++ b/crypto/cms/cms_att.c
@@ -0,0 +1,195 @@
+/* crypto/cms/cms_att.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include "cms.h"
+#include "cms_lcl.h"
+
+/* CMS SignedData Attribute utilities */
+
+int CMS_signed_get_attr_count(const CMS_SignerInfo *si)
+{
+	return X509at_get_attr_count(si->signedAttrs);
+}
+
+int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+			  int lastpos)
+{
+	return X509at_get_attr_by_NID(si->signedAttrs, nid, lastpos);
+}
+
+int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
+			  int lastpos)
+{
+	return X509at_get_attr_by_OBJ(si->signedAttrs, obj, lastpos);
+}
+
+X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc)
+{
+	return X509at_get_attr(si->signedAttrs, loc);
+}
+
+X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc)
+{
+	return X509at_delete_attr(si->signedAttrs, loc);
+}
+
+int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
+{
+	if(X509at_add1_attr(&si->signedAttrs, attr)) return 1;
+	return 0;
+}
+
+int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
+			const ASN1_OBJECT *obj, int type,
+			const void *bytes, int len)
+{
+	if(X509at_add1_attr_by_OBJ(&si->signedAttrs, obj,
+				type, bytes, len)) return 1;
+	return 0;
+}
+
+int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
+			int nid, int type,
+			const void *bytes, int len)
+{
+	if(X509at_add1_attr_by_NID(&si->signedAttrs, nid,
+				type, bytes, len)) return 1;
+	return 0;
+}
+
+int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
+			const char *attrname, int type,
+			const void *bytes, int len)
+{
+	if(X509at_add1_attr_by_txt(&si->signedAttrs, attrname,
+				type, bytes, len)) return 1;
+	return 0;
+}
+
+void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
+					int lastpos, int type)
+{
+	return X509at_get0_data_by_OBJ(si->signedAttrs, oid, lastpos, type);
+}
+
+int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si)
+{
+	return X509at_get_attr_count(si->unsignedAttrs);
+}
+
+int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+			  int lastpos)
+{
+	return X509at_get_attr_by_NID(si->unsignedAttrs, nid, lastpos);
+}
+
+int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
+			  int lastpos)
+{
+	return X509at_get_attr_by_OBJ(si->unsignedAttrs, obj, lastpos);
+}
+
+X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc)
+{
+	return X509at_get_attr(si->unsignedAttrs, loc);
+}
+
+X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc)
+{
+	return X509at_delete_attr(si->unsignedAttrs, loc);
+}
+
+int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
+{
+	if(X509at_add1_attr(&si->unsignedAttrs, attr)) return 1;
+	return 0;
+}
+
+int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
+			const ASN1_OBJECT *obj, int type,
+			const void *bytes, int len)
+{
+	if(X509at_add1_attr_by_OBJ(&si->unsignedAttrs, obj,
+				type, bytes, len)) return 1;
+	return 0;
+}
+
+int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
+			int nid, int type,
+			const void *bytes, int len)
+{
+	if(X509at_add1_attr_by_NID(&si->unsignedAttrs, nid,
+				type, bytes, len)) return 1;
+	return 0;
+}
+
+int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
+			const char *attrname, int type,
+			const void *bytes, int len)
+{
+	if(X509at_add1_attr_by_txt(&si->unsignedAttrs, attrname,
+				type, bytes, len)) return 1;
+	return 0;
+}
+
+void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
+					int lastpos, int type)
+{
+	return X509at_get0_data_by_OBJ(si->unsignedAttrs, oid, lastpos, type);
+}
+
+/* Specific attribute cases */
diff --git a/crypto/cms/cms_cd.c b/crypto/cms/cms_cd.c
new file mode 100644
index 0000000..2021688
--- /dev/null
+++ b/crypto/cms/cms_cd.c
@@ -0,0 +1,136 @@
+/* crypto/cms/cms_cd.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#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)
+
+#ifdef ZLIB
+
+/* CMS CompressedData Utilities */
+
+CMS_ContentInfo *cms_CompressedData_create(int comp_nid)
+	{
+	CMS_ContentInfo *cms;
+	CMS_CompressedData *cd;
+	/* Will need something cleverer if there is ever more than one
+	 * compression algorithm or parameters have some meaning...
+	 */
+	if (comp_nid != NID_zlib_compression)
+		{
+		CMSerr(CMS_F_CMS_COMPRESSEDDATA_CREATE,
+				CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+		return NULL;
+		}
+	cms = CMS_ContentInfo_new();
+	if (!cms)
+		return NULL;
+
+	cd = M_ASN1_new_of(CMS_CompressedData);
+
+	if (!cd)
+		goto err;
+
+	cms->contentType = OBJ_nid2obj(NID_id_smime_ct_compressedData);
+	cms->d.compressedData = cd;
+
+	cd->version = 0;
+
+	X509_ALGOR_set0(cd->compressionAlgorithm,
+			OBJ_nid2obj(NID_zlib_compression),
+			V_ASN1_UNDEF, NULL);
+
+	cd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data);
+
+	return cms;
+
+	err:
+
+	if (cms)
+		CMS_ContentInfo_free(cms);
+
+	return NULL;
+	}
+
+BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms)
+	{
+	CMS_CompressedData *cd;
+	ASN1_OBJECT *compoid;
+	if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_compressedData)
+		{
+		CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
+				CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA);
+		return NULL;
+		}
+	cd = cms->d.compressedData;
+	X509_ALGOR_get0(&compoid, NULL, NULL, cd->compressionAlgorithm);
+	if (OBJ_obj2nid(compoid) != NID_zlib_compression)
+		{
+		CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
+				CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+		return NULL;
+		}
+	return BIO_new(BIO_f_zlib());
+	}
+
+#endif
diff --git a/crypto/cms/cms_dd.c b/crypto/cms/cms_dd.c
new file mode 100644
index 0000000..8919c15
--- /dev/null
+++ b/crypto/cms/cms_dd.c
@@ -0,0 +1,148 @@
+/* crypto/cms/cms_dd.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include "cms_lcl.h"
+
+DECLARE_ASN1_ITEM(CMS_DigestedData)
+
+/* CMS DigestedData Utilities */
+
+CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md)
+	{
+	CMS_ContentInfo *cms;
+	CMS_DigestedData *dd;
+	cms = CMS_ContentInfo_new();
+	if (!cms)
+		return NULL;
+
+	dd = M_ASN1_new_of(CMS_DigestedData);
+
+	if (!dd)
+		goto err;
+
+	cms->contentType = OBJ_nid2obj(NID_pkcs7_digest);
+	cms->d.digestedData = dd;
+
+	dd->version = 0;
+	dd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data);
+
+	cms_DigestAlgorithm_set(dd->digestAlgorithm, md);
+
+	return cms;
+
+	err:
+
+	if (cms)
+		CMS_ContentInfo_free(cms);
+
+	return NULL;
+	}
+
+BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms)
+	{
+	CMS_DigestedData *dd;
+	dd = cms->d.digestedData;
+	return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm);
+	}
+
+int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify)
+	{
+	EVP_MD_CTX mctx;
+	unsigned char md[EVP_MAX_MD_SIZE];
+	unsigned int mdlen;
+	int r = 0;
+	CMS_DigestedData *dd;
+	EVP_MD_CTX_init(&mctx);
+
+	dd = cms->d.digestedData;
+
+	if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, dd->digestAlgorithm))
+		goto err;
+
+	if (EVP_DigestFinal_ex(&mctx, md, &mdlen) <= 0)
+		goto err;
+
+	if (verify)
+		{
+		if (mdlen != (unsigned int)dd->digest->length)
+			{
+			CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
+				CMS_R_MESSAGEDIGEST_WRONG_LENGTH);
+			goto err;
+			}
+
+		if (memcmp(md, dd->digest->data, mdlen))
+			CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
+				CMS_R_VERIFICATION_FAILURE);
+		else
+			r = 1;
+		}
+	else
+		{
+		if (!ASN1_STRING_set(dd->digest, md, mdlen))
+			goto err;
+		r = 1;
+		}
+
+	err:
+	EVP_MD_CTX_cleanup(&mctx);
+
+	return r;
+
+	}
diff --git a/crypto/cms/cms_enc.c b/crypto/cms/cms_enc.c
new file mode 100644
index 0000000..bebeaf2
--- /dev/null
+++ b/crypto/cms/cms_enc.c
@@ -0,0 +1,294 @@
+/* crypto/cms/cms_enc.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include <openssl/rand.h>
+#include "cms_lcl.h"
+
+/* CMS EncryptedData Utilities */
+
+DECLARE_ASN1_ITEM(CMS_EncryptedData)
+
+/* Return BIO based on EncryptedContentInfo and key */
+
+BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
+	{
+	BIO *b;
+	EVP_CIPHER_CTX *ctx;
+	const EVP_CIPHER *ciph;
+	X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
+	unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL;
+	unsigned char *tkey = NULL;
+	size_t tkeylen = 0;
+
+	int ok = 0;
+
+	int enc, keep_key = 0;
+
+	enc = ec->cipher ? 1 : 0;
+
+	b = BIO_new(BIO_f_cipher());
+	if (!b)
+		{
+		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+							ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+
+	BIO_get_cipher_ctx(b, &ctx);
+
+	if (enc)
+		{
+		ciph = ec->cipher;
+		/* If not keeping key set cipher to NULL so subsequent calls
+		 * decrypt.
+		 */
+		if (ec->key)
+			ec->cipher = NULL;
+		}
+	else
+		{
+		ciph = EVP_get_cipherbyobj(calg->algorithm);
+
+		if (!ciph)
+			{
+			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+							CMS_R_UNKNOWN_CIPHER);
+			goto err;
+			}
+		}
+
+	if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0)
+		{
+		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+				CMS_R_CIPHER_INITIALISATION_ERROR);
+		goto err;
+		}
+
+	if (enc)
+		{
+		int ivlen;
+		calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx));
+		/* Generate a random IV if we need one */
+		ivlen = EVP_CIPHER_CTX_iv_length(ctx);
+		if (ivlen > 0)
+			{
+			if (RAND_pseudo_bytes(iv, ivlen) <= 0)
+				goto err;
+			piv = iv;
+			}
+		}
+	else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0)
+		{
+		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
+		goto err;
+		}
+	tkeylen = EVP_CIPHER_CTX_key_length(ctx);
+	/* Generate random session key */
+	if (!enc || !ec->key)
+		{
+		tkey = OPENSSL_malloc(tkeylen);
+		if (!tkey)
+			{
+			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+							ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0)
+			goto err;
+		}
+
+	if (!ec->key)
+		{
+		ec->key = tkey;
+		ec->keylen = tkeylen;
+		tkey = NULL;
+		if (enc)
+			keep_key = 1;
+		else
+			ERR_clear_error();
+		
+		}
+
+	if (ec->keylen != tkeylen)
+		{
+		/* If necessary set key length */
+		if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0)
+			{
+			/* Only reveal failure if debugging so we don't
+			 * leak information which may be useful in MMA.
+			 */
+			if (enc || ec->debug)
+				{
+				CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+						CMS_R_INVALID_KEY_LENGTH);
+				goto err;
+				}
+			else
+				{
+				/* Use random key */
+				OPENSSL_cleanse(ec->key, ec->keylen);
+				OPENSSL_free(ec->key);
+				ec->key = tkey;
+				ec->keylen = tkeylen;
+				tkey = NULL;
+				ERR_clear_error();
+				}
+			}
+		}
+
+	if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0)
+		{
+		CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+				CMS_R_CIPHER_INITIALISATION_ERROR);
+		goto err;
+		}
+
+	if (piv)
+		{
+		calg->parameter = ASN1_TYPE_new();
+		if (!calg->parameter)
+			{
+			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+							ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0)
+			{
+			CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
+				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
+			goto err;
+			}
+		}
+	ok = 1;
+
+	err:
+	if (ec->key && !keep_key)
+		{
+		OPENSSL_cleanse(ec->key, ec->keylen);
+		OPENSSL_free(ec->key);
+		ec->key = NULL;
+		}
+	if (tkey)
+		{
+		OPENSSL_cleanse(tkey, tkeylen);
+		OPENSSL_free(tkey);
+		}
+	if (ok)
+		return b;
+	BIO_free(b);
+	return NULL;
+	}
+
+int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, 
+				const EVP_CIPHER *cipher,
+				const unsigned char *key, size_t keylen)
+	{
+	ec->cipher = cipher;
+	if (key)
+		{
+		ec->key = OPENSSL_malloc(keylen);
+		if (!ec->key)
+			return 0;
+		memcpy(ec->key, key, keylen);
+		}
+	ec->keylen = keylen;
+	if (cipher)
+		ec->contentType = OBJ_nid2obj(NID_pkcs7_data);
+	return 1;
+	}
+
+int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
+				const unsigned char *key, size_t keylen)
+	{
+	CMS_EncryptedContentInfo *ec;
+	if (!key || !keylen)
+		{
+		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY);
+		return 0;
+		}
+	if (ciph)
+		{
+		cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData);
+		if (!cms->d.encryptedData)
+			{
+			CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY,
+				ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted);
+		cms->d.encryptedData->version = 0;
+		}
+	else if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted)
+		{
+		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY,
+						CMS_R_NOT_ENCRYPTED_DATA);
+		return 0;
+		}
+	ec = cms->d.encryptedData->encryptedContentInfo;
+	return cms_EncryptedContent_init(ec, ciph, key, keylen);
+	}
+
+BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms)
+	{
+	CMS_EncryptedData *enc = cms->d.encryptedData;
+	if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs)
+		enc->version = 2;
+	return cms_EncryptedContent_init_bio(enc->encryptedContentInfo);
+	}
diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c
new file mode 100644
index 0000000..be20b1c
--- /dev/null
+++ b/crypto/cms/cms_env.c
@@ -0,0 +1,876 @@
+/* crypto/cms/cms_env.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include <openssl/rand.h>
+#include <openssl/aes.h>
+#include "cms_lcl.h"
+#include "asn1_locl.h"
+
+/* CMS EnvelopedData Utilities */
+
+DECLARE_ASN1_ITEM(CMS_EnvelopedData)
+DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo)
+DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo)
+DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute)
+
+DECLARE_STACK_OF(CMS_RecipientInfo)
+
+CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms)
+	{
+	if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped)
+		{
+		CMSerr(CMS_F_CMS_GET0_ENVELOPED,
+				CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
+		return NULL;
+		}
+	return cms->d.envelopedData;
+	}
+
+static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
+	{
+	if (cms->d.other == NULL)
+		{
+		cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData);
+		if (!cms->d.envelopedData)
+			{
+			CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT,
+							ERR_R_MALLOC_FAILURE);
+			return NULL;
+			}
+		cms->d.envelopedData->version = 0;
+		cms->d.envelopedData->encryptedContentInfo->contentType =
+						OBJ_nid2obj(NID_pkcs7_data);
+		ASN1_OBJECT_free(cms->contentType);
+		cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped);
+		return cms->d.envelopedData;
+		}
+	return cms_get0_enveloped(cms);
+	}
+
+STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
+	{
+	CMS_EnvelopedData *env;
+	env = cms_get0_enveloped(cms);
+	if (!env)
+		return NULL;
+	return env->recipientInfos;
+	}
+
+int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
+	{
+	return ri->type;
+	}
+
+CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
+	{
+	CMS_ContentInfo *cms;
+	CMS_EnvelopedData *env;
+	cms = CMS_ContentInfo_new();
+	if (!cms)
+		goto merr;
+	env = cms_enveloped_data_init(cms);
+	if (!env)
+		goto merr;
+	if (!cms_EncryptedContent_init(env->encryptedContentInfo,
+					cipher, NULL, 0))
+		goto merr;
+	return cms;
+	merr:
+	if (cms)
+		CMS_ContentInfo_free(cms);
+	CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE);
+	return NULL;
+	}
+
+/* Key Transport Recipient Info (KTRI) routines */
+
+/* Add a recipient certificate. For now only handle key transport.
+ * If we ever handle key agreement will need updating.
+ */
+
+CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
+					X509 *recip, unsigned int flags)
+	{
+	CMS_RecipientInfo *ri = NULL;
+	CMS_KeyTransRecipientInfo *ktri;
+	CMS_EnvelopedData *env;
+	EVP_PKEY *pk = NULL;
+	int i, type;
+	env = cms_get0_enveloped(cms);
+	if (!env)
+		goto err;
+
+	/* Initialize recipient info */
+	ri = M_ASN1_new_of(CMS_RecipientInfo);
+	if (!ri)
+		goto merr;
+
+	/* Initialize and add key transport recipient info */
+
+	ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo);
+	if (!ri->d.ktri)
+		goto merr;
+	ri->type = CMS_RECIPINFO_TRANS;
+
+	ktri = ri->d.ktri;
+
+	X509_check_purpose(recip, -1, -1);
+	pk = X509_get_pubkey(recip);
+	if (!pk)
+		{
+		CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
+				CMS_R_ERROR_GETTING_PUBLIC_KEY);
+		goto err;
+		}
+	CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509);
+	ktri->pkey = pk;
+	ktri->recip = recip;
+
+	if (flags & CMS_USE_KEYID)
+		{
+		ktri->version = 2;
+		type = CMS_RECIPINFO_KEYIDENTIFIER;
+		}
+	else
+		{
+		ktri->version = 0;
+		type = CMS_RECIPINFO_ISSUER_SERIAL;
+		}
+
+	/* Not a typo: RecipientIdentifier and SignerIdentifier are the
+	 * same structure.
+	 */
+
+	if (!cms_set1_SignerIdentifier(ktri->rid, recip, type))
+		goto err;
+
+	if (pk->ameth && pk->ameth->pkey_ctrl)
+		{
+		i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_ENVELOPE,
+						0, ri);
+		if (i == -2)
+			{
+			CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
+				CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+			goto err;
+			}
+		if (i <= 0)
+			{
+			CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
+				CMS_R_CTRL_FAILURE);
+			goto err;
+			}
+		}
+
+	if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
+		goto merr;
+
+	return ri;
+
+	merr:
+	CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE);
+	err:
+	if (ri)
+		M_ASN1_free_of(ri, CMS_RecipientInfo);
+	return NULL;
+
+	}
+
+int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
+					EVP_PKEY **pk, X509 **recip,
+					X509_ALGOR **palg)
+	{
+	CMS_KeyTransRecipientInfo *ktri;
+	if (ri->type != CMS_RECIPINFO_TRANS)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS,
+			CMS_R_NOT_KEY_TRANSPORT);
+		return 0;
+		}
+
+	ktri = ri->d.ktri;
+
+	if (pk)
+		*pk = ktri->pkey;
+	if (recip)
+		*recip = ktri->recip;
+	if (palg)
+		*palg = ktri->keyEncryptionAlgorithm;
+	return 1;
+	}
+
+int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
+					ASN1_OCTET_STRING **keyid,
+					X509_NAME **issuer, ASN1_INTEGER **sno)
+	{
+	CMS_KeyTransRecipientInfo *ktri;
+	if (ri->type != CMS_RECIPINFO_TRANS)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID,
+			CMS_R_NOT_KEY_TRANSPORT);
+		return 0;
+		}
+	ktri = ri->d.ktri;
+
+	return cms_SignerIdentifier_get0_signer_id(ktri->rid,
+							keyid, issuer, sno);
+	}
+
+int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
+	{
+	if (ri->type != CMS_RECIPINFO_TRANS)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP,
+			CMS_R_NOT_KEY_TRANSPORT);
+		return -2;
+		}
+	return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
+	}
+
+int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey)
+	{
+	if (ri->type != CMS_RECIPINFO_TRANS)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY,
+			CMS_R_NOT_KEY_TRANSPORT);
+		return 0;
+		}
+	ri->d.ktri->pkey = pkey;
+	return 1;
+	}
+
+/* Encrypt content key in key transport recipient info */
+
+static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
+					CMS_RecipientInfo *ri)
+	{
+	CMS_KeyTransRecipientInfo *ktri;
+	CMS_EncryptedContentInfo *ec;
+	EVP_PKEY_CTX *pctx = NULL;
+	unsigned char *ek = NULL;
+	size_t eklen;
+
+	int ret = 0;
+
+	if (ri->type != CMS_RECIPINFO_TRANS)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
+			CMS_R_NOT_KEY_TRANSPORT);
+		return 0;
+		}
+	ktri = ri->d.ktri;
+	ec = cms->d.envelopedData->encryptedContentInfo;
+
+	pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
+	if (!pctx)
+		return 0;
+
+	if (EVP_PKEY_encrypt_init(pctx) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
+				EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR);
+		goto err;
+		}
+
+	if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0)
+		goto err;
+
+	ek = OPENSSL_malloc(eklen);
+
+	if (ek == NULL)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT,
+							ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
+		goto err;
+
+	ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
+	ek = NULL;
+
+	ret = 1;
+
+	err:
+	if (pctx)
+		EVP_PKEY_CTX_free(pctx);
+	if (ek)
+		OPENSSL_free(ek);
+	return ret;
+
+	}
+
+/* Decrypt content key from KTRI */
+
+static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
+							CMS_RecipientInfo *ri)
+	{
+	CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
+	EVP_PKEY_CTX *pctx = NULL;
+	unsigned char *ek = NULL;
+	size_t eklen;
+	int ret = 0;
+	CMS_EncryptedContentInfo *ec;
+	ec = cms->d.envelopedData->encryptedContentInfo;
+
+	if (ktri->pkey == NULL)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
+			CMS_R_NO_PRIVATE_KEY);
+		return 0;
+		}
+
+	pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
+	if (!pctx)
+		return 0;
+
+	if (EVP_PKEY_decrypt_init(pctx) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
+				EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR);
+		goto err;
+		}
+
+	if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
+				ktri->encryptedKey->data,
+				ktri->encryptedKey->length) <= 0)
+		goto err;
+
+	ek = OPENSSL_malloc(eklen);
+
+	if (ek == NULL)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT,
+							ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	if (EVP_PKEY_decrypt(pctx, ek, &eklen,
+				ktri->encryptedKey->data,
+				ktri->encryptedKey->length) <= 0)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
+		goto err;
+		}
+
+	ret = 1;
+
+	if (ec->key)
+		{
+		OPENSSL_cleanse(ec->key, ec->keylen);
+		OPENSSL_free(ec->key);
+		}
+
+	ec->key = ek;
+	ec->keylen = eklen;
+
+	err:
+	if (pctx)
+		EVP_PKEY_CTX_free(pctx);
+	if (!ret && ek)
+		OPENSSL_free(ek);
+
+	return ret;
+	}
+
+/* Key Encrypted Key (KEK) RecipientInfo routines */
+
+int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, 
+					const unsigned char *id, size_t idlen)
+	{
+	ASN1_OCTET_STRING tmp_os;
+	CMS_KEKRecipientInfo *kekri;
+	if (ri->type != CMS_RECIPINFO_KEK)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK);
+		return -2;
+		}
+	kekri = ri->d.kekri;
+	tmp_os.type = V_ASN1_OCTET_STRING;
+	tmp_os.flags = 0;
+	tmp_os.data = (unsigned char *)id;
+	tmp_os.length = (int)idlen;
+	return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier);
+	}
+
+/* For now hard code AES key wrap info */
+
+static size_t aes_wrap_keylen(int nid)
+	{
+	switch (nid)
+		{
+		case NID_id_aes128_wrap:
+		return 16;
+
+		case NID_id_aes192_wrap:
+		return  24;
+
+		case NID_id_aes256_wrap:
+		return  32;
+
+		default:
+		return 0;
+		}
+	}
+
+CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
+					unsigned char *key, size_t keylen,
+					unsigned char *id, size_t idlen,
+					ASN1_GENERALIZEDTIME *date,
+					ASN1_OBJECT *otherTypeId,
+					ASN1_TYPE *otherType)
+	{
+	CMS_RecipientInfo *ri = NULL;
+	CMS_EnvelopedData *env;
+	CMS_KEKRecipientInfo *kekri;
+	env = cms_get0_enveloped(cms);
+	if (!env)
+		goto err;
+
+	if (nid == NID_undef)
+		{
+		switch (keylen)
+			{
+			case 16:
+			nid = NID_id_aes128_wrap;
+			break;
+
+			case  24:
+			nid = NID_id_aes192_wrap;
+			break;
+
+			case  32:
+			nid = NID_id_aes256_wrap;
+			break;
+
+			default:
+			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
+						CMS_R_INVALID_KEY_LENGTH);
+			goto err;
+			}
+
+		}
+	else
+		{
+
+		size_t exp_keylen = aes_wrap_keylen(nid);
+
+		if (!exp_keylen)
+			{
+			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
+					CMS_R_UNSUPPORTED_KEK_ALGORITHM);
+			goto err;
+			}
+
+		if (keylen != exp_keylen)
+			{
+			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
+					CMS_R_INVALID_KEY_LENGTH);
+			goto err;
+			}
+
+		}
+
+	/* Initialize recipient info */
+	ri = M_ASN1_new_of(CMS_RecipientInfo);
+	if (!ri)
+		goto merr;
+
+	ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo);
+	if (!ri->d.kekri)
+		goto merr;
+	ri->type = CMS_RECIPINFO_KEK;
+
+	kekri = ri->d.kekri;
+
+	if (otherTypeId)
+		{
+		kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute);
+		if (kekri->kekid->other == NULL)
+			goto merr;
+		}
+
+	if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
+		goto merr;
+
+
+	/* After this point no calls can fail */
+
+	kekri->version = 4;
+
+	kekri->key = key;
+	kekri->keylen = keylen;
+
+	ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen);
+
+	kekri->kekid->date = date;
+
+	if (kekri->kekid->other)
+		{
+		kekri->kekid->other->keyAttrId = otherTypeId;
+		kekri->kekid->other->keyAttr = otherType;
+		}
+
+	X509_ALGOR_set0(kekri->keyEncryptionAlgorithm,
+				OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL);
+
+	return ri;
+
+	merr:
+	CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE);
+	err:
+	if (ri)
+		M_ASN1_free_of(ri, CMS_RecipientInfo);
+	return NULL;
+
+	}
+
+int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
+					X509_ALGOR **palg,
+					ASN1_OCTET_STRING **pid,
+					ASN1_GENERALIZEDTIME **pdate,
+					ASN1_OBJECT **potherid,
+					ASN1_TYPE **pothertype)
+	{
+	CMS_KEKIdentifier *rkid;
+	if (ri->type != CMS_RECIPINFO_KEK)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK);
+		return 0;
+		}
+	rkid =  ri->d.kekri->kekid;
+	if (palg)
+		*palg = ri->d.kekri->keyEncryptionAlgorithm;
+	if (pid)
+		*pid = rkid->keyIdentifier;
+	if (pdate)
+		*pdate = rkid->date;
+	if (potherid)
+		{
+		if (rkid->other)
+			*potherid = rkid->other->keyAttrId;
+		else
+			*potherid = NULL;
+		}
+	if (pothertype)
+		{
+		if (rkid->other)
+			*pothertype = rkid->other->keyAttr;
+		else
+			*pothertype = NULL;
+		}
+	return 1;
+	}
+
+int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, 
+				unsigned char *key, size_t keylen)
+	{
+	CMS_KEKRecipientInfo *kekri;
+	if (ri->type != CMS_RECIPINFO_KEK)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK);
+		return 0;
+		}
+
+	kekri = ri->d.kekri;
+	kekri->key = key;
+	kekri->keylen = keylen;
+	return 1;
+	}
+
+
+/* Encrypt content key in KEK recipient info */
+
+static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms,
+					CMS_RecipientInfo *ri)
+	{
+	CMS_EncryptedContentInfo *ec;
+	CMS_KEKRecipientInfo *kekri;
+	AES_KEY actx;
+	unsigned char *wkey = NULL;
+	int wkeylen;
+	int r = 0;
+
+	ec = cms->d.envelopedData->encryptedContentInfo;
+
+	kekri = ri->d.kekri;
+
+	if (!kekri->key)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY);
+		return 0;
+		}
+
+	if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx))
+		{ 
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
+						CMS_R_ERROR_SETTING_KEY);
+		goto err;
+		}
+
+	wkey = OPENSSL_malloc(ec->keylen + 8);
+
+	if (!wkey)
+		{ 
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
+						ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen);
+
+	if (wkeylen <= 0)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR);
+		goto err;
+		}
+
+	ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen);
+
+	r = 1;
+
+	err:
+
+	if (!r && wkey)
+		OPENSSL_free(wkey);
+	OPENSSL_cleanse(&actx, sizeof(actx));
+
+	return r;
+
+	}
+
+/* Decrypt content key in KEK recipient info */
+
+static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
+					CMS_RecipientInfo *ri)
+	{
+	CMS_EncryptedContentInfo *ec;
+	CMS_KEKRecipientInfo *kekri;
+	AES_KEY actx;
+	unsigned char *ukey = NULL;
+	int ukeylen;
+	int r = 0, wrap_nid;
+
+	ec = cms->d.envelopedData->encryptedContentInfo;
+
+	kekri = ri->d.kekri;
+
+	if (!kekri->key)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY);
+		return 0;
+		}
+
+	wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm);
+	if (aes_wrap_keylen(wrap_nid) != kekri->keylen)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
+			CMS_R_INVALID_KEY_LENGTH);
+		return 0;
+		}
+
+	/* If encrypted key length is invalid don't bother */
+
+	if (kekri->encryptedKey->length < 16)
+		{ 
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
+					CMS_R_INVALID_ENCRYPTED_KEY_LENGTH);
+		goto err;
+		}
+
+	if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx))
+		{ 
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
+						CMS_R_ERROR_SETTING_KEY);
+		goto err;
+		}
+
+	ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);
+
+	if (!ukey)
+		{ 
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
+						ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	ukeylen = AES_unwrap_key(&actx, NULL, ukey,
+					kekri->encryptedKey->data,
+					kekri->encryptedKey->length);
+
+	if (ukeylen <= 0)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
+							CMS_R_UNWRAP_ERROR);
+		goto err;
+		}
+
+	ec->key = ukey;
+	ec->keylen = ukeylen;
+
+	r = 1;
+
+	err:
+
+	if (!r && ukey)
+		OPENSSL_free(ukey);
+	OPENSSL_cleanse(&actx, sizeof(actx));
+
+	return r;
+
+	}
+
+int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
+	{
+	switch(ri->type)
+		{
+		case CMS_RECIPINFO_TRANS:
+		return cms_RecipientInfo_ktri_decrypt(cms, ri);
+
+		case CMS_RECIPINFO_KEK:
+		return cms_RecipientInfo_kekri_decrypt(cms, ri);
+
+		case CMS_RECIPINFO_PASS:
+		return cms_RecipientInfo_pwri_crypt(cms, ri, 0);
+
+		default:
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
+			CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE);
+		return 0;
+		}
+	}
+
+BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
+	{
+	CMS_EncryptedContentInfo *ec;
+	STACK_OF(CMS_RecipientInfo) *rinfos;
+	CMS_RecipientInfo *ri;
+	int i, r, ok = 0;
+	BIO *ret;
+
+	/* Get BIO first to set up key */
+
+	ec = cms->d.envelopedData->encryptedContentInfo;
+	ret = cms_EncryptedContent_init_bio(ec);
+
+	/* If error or no cipher end of processing */
+
+	if (!ret || !ec->cipher)
+		return ret;
+
+	/* Now encrypt content key according to each RecipientInfo type */
+
+	rinfos = cms->d.envelopedData->recipientInfos;
+
+	for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++)
+		{
+		ri = sk_CMS_RecipientInfo_value(rinfos, i);
+
+		switch (ri->type)
+			{
+			case CMS_RECIPINFO_TRANS:
+			r = cms_RecipientInfo_ktri_encrypt(cms, ri);
+			break;
+
+			case CMS_RECIPINFO_KEK:
+			r = cms_RecipientInfo_kekri_encrypt(cms, ri);
+			break;
+
+			case CMS_RECIPINFO_PASS:
+			r = cms_RecipientInfo_pwri_crypt(cms, ri, 1);
+			break;
+
+			default:
+			CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
+				CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
+			goto err;
+			}
+
+		if (r <= 0)
+			{
+			CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
+				CMS_R_ERROR_SETTING_RECIPIENTINFO);
+			goto err;
+			}
+		}
+
+	ok = 1;
+
+	err:
+	ec->cipher = NULL;
+	if (ec->key)
+		{
+		OPENSSL_cleanse(ec->key, ec->keylen);
+		OPENSSL_free(ec->key);
+		ec->key = NULL;
+		ec->keylen = 0;
+		}
+	if (ok)
+		return ret;
+	BIO_free(ret);
+	return NULL;
+
+	}
diff --git a/crypto/cms/cms_err.c b/crypto/cms/cms_err.c
new file mode 100644
index 0000000..8330ead
--- /dev/null
+++ b/crypto/cms/cms_err.c
@@ -0,0 +1,245 @@
+/* crypto/cms/cms_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2009 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* NOTE: this file was auto generated by the mkerr.pl script: any changes
+ * made to it will be overwritten when the script next updates this file,
+ * only reason strings will be preserved.
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_CMS,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_CMS,0,reason)
+
+static ERR_STRING_DATA CMS_str_functs[]=
+	{
+{ERR_FUNC(CMS_F_CHECK_CONTENT),	"CHECK_CONTENT"},
+{ERR_FUNC(CMS_F_CMS_ADD0_CERT),	"CMS_add0_cert"},
+{ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_KEY),	"CMS_add0_recipient_key"},
+{ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD),	"CMS_add0_recipient_password"},
+{ERR_FUNC(CMS_F_CMS_ADD1_RECEIPTREQUEST),	"CMS_add1_ReceiptRequest"},
+{ERR_FUNC(CMS_F_CMS_ADD1_RECIPIENT_CERT),	"CMS_add1_recipient_cert"},
+{ERR_FUNC(CMS_F_CMS_ADD1_SIGNER),	"CMS_add1_signer"},
+{ERR_FUNC(CMS_F_CMS_ADD1_SIGNINGTIME),	"CMS_ADD1_SIGNINGTIME"},
+{ERR_FUNC(CMS_F_CMS_COMPRESS),	"CMS_compress"},
+{ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_CREATE),	"cms_CompressedData_create"},
+{ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO),	"cms_CompressedData_init_bio"},
+{ERR_FUNC(CMS_F_CMS_COPY_CONTENT),	"CMS_COPY_CONTENT"},
+{ERR_FUNC(CMS_F_CMS_COPY_MESSAGEDIGEST),	"CMS_COPY_MESSAGEDIGEST"},
+{ERR_FUNC(CMS_F_CMS_DATA),	"CMS_data"},
+{ERR_FUNC(CMS_F_CMS_DATAFINAL),	"CMS_dataFinal"},
+{ERR_FUNC(CMS_F_CMS_DATAINIT),	"CMS_dataInit"},
+{ERR_FUNC(CMS_F_CMS_DECRYPT),	"CMS_decrypt"},
+{ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_KEY),	"CMS_decrypt_set1_key"},
+{ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PASSWORD),	"CMS_decrypt_set1_password"},
+{ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PKEY),	"CMS_decrypt_set1_pkey"},
+{ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX),	"cms_DigestAlgorithm_find_ctx"},
+{ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO),	"cms_DigestAlgorithm_init_bio"},
+{ERR_FUNC(CMS_F_CMS_DIGESTEDDATA_DO_FINAL),	"cms_DigestedData_do_final"},
+{ERR_FUNC(CMS_F_CMS_DIGEST_VERIFY),	"CMS_digest_verify"},
+{ERR_FUNC(CMS_F_CMS_ENCODE_RECEIPT),	"cms_encode_Receipt"},
+{ERR_FUNC(CMS_F_CMS_ENCRYPT),	"CMS_encrypt"},
+{ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO),	"cms_EncryptedContent_init_bio"},
+{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT),	"CMS_EncryptedData_decrypt"},
+{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT),	"CMS_EncryptedData_encrypt"},
+{ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY),	"CMS_EncryptedData_set1_key"},
+{ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_CREATE),	"CMS_EnvelopedData_create"},
+{ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO),	"cms_EnvelopedData_init_bio"},
+{ERR_FUNC(CMS_F_CMS_ENVELOPED_DATA_INIT),	"CMS_ENVELOPED_DATA_INIT"},
+{ERR_FUNC(CMS_F_CMS_FINAL),	"CMS_final"},
+{ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES),	"CMS_GET0_CERTIFICATE_CHOICES"},
+{ERR_FUNC(CMS_F_CMS_GET0_CONTENT),	"CMS_get0_content"},
+{ERR_FUNC(CMS_F_CMS_GET0_ECONTENT_TYPE),	"CMS_GET0_ECONTENT_TYPE"},
+{ERR_FUNC(CMS_F_CMS_GET0_ENVELOPED),	"cms_get0_enveloped"},
+{ERR_FUNC(CMS_F_CMS_GET0_REVOCATION_CHOICES),	"CMS_GET0_REVOCATION_CHOICES"},
+{ERR_FUNC(CMS_F_CMS_GET0_SIGNED),	"CMS_GET0_SIGNED"},
+{ERR_FUNC(CMS_F_CMS_MSGSIGDIGEST_ADD1),	"cms_msgSigDigest_add1"},
+{ERR_FUNC(CMS_F_CMS_RECEIPTREQUEST_CREATE0),	"CMS_ReceiptRequest_create0"},
+{ERR_FUNC(CMS_F_CMS_RECEIPT_VERIFY),	"cms_Receipt_verify"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_DECRYPT),	"CMS_RecipientInfo_decrypt"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT),	"CMS_RECIPIENTINFO_KEKRI_DECRYPT"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT),	"CMS_RECIPIENTINFO_KEKRI_ENCRYPT"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID),	"CMS_RecipientInfo_kekri_get0_id"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP),	"CMS_RecipientInfo_kekri_id_cmp"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP),	"CMS_RecipientInfo_ktri_cert_cmp"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT),	"CMS_RECIPIENTINFO_KTRI_DECRYPT"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT),	"CMS_RECIPIENTINFO_KTRI_ENCRYPT"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS),	"CMS_RecipientInfo_ktri_get0_algs"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID),	"CMS_RecipientInfo_ktri_get0_signer_id"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT),	"cms_RecipientInfo_pwri_crypt"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_KEY),	"CMS_RecipientInfo_set0_key"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD),	"CMS_RecipientInfo_set0_password"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY),	"CMS_RecipientInfo_set0_pkey"},
+{ERR_FUNC(CMS_F_CMS_SET1_SIGNERIDENTIFIER),	"cms_set1_SignerIdentifier"},
+{ERR_FUNC(CMS_F_CMS_SET_DETACHED),	"CMS_set_detached"},
+{ERR_FUNC(CMS_F_CMS_SIGN),	"CMS_sign"},
+{ERR_FUNC(CMS_F_CMS_SIGNED_DATA_INIT),	"CMS_SIGNED_DATA_INIT"},
+{ERR_FUNC(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN),	"CMS_SIGNERINFO_CONTENT_SIGN"},
+{ERR_FUNC(CMS_F_CMS_SIGNERINFO_SIGN),	"CMS_SignerInfo_sign"},
+{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY),	"CMS_SignerInfo_verify"},
+{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CERT),	"CMS_SIGNERINFO_VERIFY_CERT"},
+{ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT),	"CMS_SignerInfo_verify_content"},
+{ERR_FUNC(CMS_F_CMS_SIGN_RECEIPT),	"CMS_sign_receipt"},
+{ERR_FUNC(CMS_F_CMS_STREAM),	"CMS_stream"},
+{ERR_FUNC(CMS_F_CMS_UNCOMPRESS),	"CMS_uncompress"},
+{ERR_FUNC(CMS_F_CMS_VERIFY),	"CMS_verify"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA CMS_str_reasons[]=
+	{
+{ERR_REASON(CMS_R_ADD_SIGNER_ERROR)      ,"add signer error"},
+{ERR_REASON(CMS_R_CERTIFICATE_ALREADY_PRESENT),"certificate already present"},
+{ERR_REASON(CMS_R_CERTIFICATE_HAS_NO_KEYID),"certificate has no keyid"},
+{ERR_REASON(CMS_R_CERTIFICATE_VERIFY_ERROR),"certificate verify error"},
+{ERR_REASON(CMS_R_CIPHER_INITIALISATION_ERROR),"cipher initialisation error"},
+{ERR_REASON(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR),"cipher parameter initialisation error"},
+{ERR_REASON(CMS_R_CMS_DATAFINAL_ERROR)   ,"cms datafinal error"},
+{ERR_REASON(CMS_R_CMS_LIB)               ,"cms lib"},
+{ERR_REASON(CMS_R_CONTENTIDENTIFIER_MISMATCH),"contentidentifier mismatch"},
+{ERR_REASON(CMS_R_CONTENT_NOT_FOUND)     ,"content not found"},
+{ERR_REASON(CMS_R_CONTENT_TYPE_MISMATCH) ,"content type mismatch"},
+{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA),"content type not compressed data"},
+{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA),"content type not enveloped data"},
+{ERR_REASON(CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA),"content type not signed data"},
+{ERR_REASON(CMS_R_CONTENT_VERIFY_ERROR)  ,"content verify error"},
+{ERR_REASON(CMS_R_CTRL_ERROR)            ,"ctrl error"},
+{ERR_REASON(CMS_R_CTRL_FAILURE)          ,"ctrl failure"},
+{ERR_REASON(CMS_R_DECRYPT_ERROR)         ,"decrypt error"},
+{ERR_REASON(CMS_R_DIGEST_ERROR)          ,"digest error"},
+{ERR_REASON(CMS_R_ERROR_GETTING_PUBLIC_KEY),"error getting public key"},
+{ERR_REASON(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE),"error reading messagedigest attribute"},
+{ERR_REASON(CMS_R_ERROR_SETTING_KEY)     ,"error setting key"},
+{ERR_REASON(CMS_R_ERROR_SETTING_RECIPIENTINFO),"error setting recipientinfo"},
+{ERR_REASON(CMS_R_INVALID_ENCRYPTED_KEY_LENGTH),"invalid encrypted key length"},
+{ERR_REASON(CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER),"invalid key encryption parameter"},
+{ERR_REASON(CMS_R_INVALID_KEY_LENGTH)    ,"invalid key length"},
+{ERR_REASON(CMS_R_MD_BIO_INIT_ERROR)     ,"md bio init error"},
+{ERR_REASON(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH),"messagedigest attribute wrong length"},
+{ERR_REASON(CMS_R_MESSAGEDIGEST_WRONG_LENGTH),"messagedigest wrong length"},
+{ERR_REASON(CMS_R_MSGSIGDIGEST_ERROR)    ,"msgsigdigest error"},
+{ERR_REASON(CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE),"msgsigdigest verification failure"},
+{ERR_REASON(CMS_R_MSGSIGDIGEST_WRONG_LENGTH),"msgsigdigest wrong length"},
+{ERR_REASON(CMS_R_NEED_ONE_SIGNER)       ,"need one signer"},
+{ERR_REASON(CMS_R_NOT_A_SIGNED_RECEIPT)  ,"not a signed receipt"},
+{ERR_REASON(CMS_R_NOT_ENCRYPTED_DATA)    ,"not encrypted data"},
+{ERR_REASON(CMS_R_NOT_KEK)               ,"not kek"},
+{ERR_REASON(CMS_R_NOT_KEY_TRANSPORT)     ,"not key transport"},
+{ERR_REASON(CMS_R_NOT_PWRI)              ,"not pwri"},
+{ERR_REASON(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"not supported for this key type"},
+{ERR_REASON(CMS_R_NO_CIPHER)             ,"no cipher"},
+{ERR_REASON(CMS_R_NO_CONTENT)            ,"no content"},
+{ERR_REASON(CMS_R_NO_CONTENT_TYPE)       ,"no content type"},
+{ERR_REASON(CMS_R_NO_DEFAULT_DIGEST)     ,"no default digest"},
+{ERR_REASON(CMS_R_NO_DIGEST_SET)         ,"no digest set"},
+{ERR_REASON(CMS_R_NO_KEY)                ,"no key"},
+{ERR_REASON(CMS_R_NO_KEY_OR_CERT)        ,"no key or cert"},
+{ERR_REASON(CMS_R_NO_MATCHING_DIGEST)    ,"no matching digest"},
+{ERR_REASON(CMS_R_NO_MATCHING_RECIPIENT) ,"no matching recipient"},
+{ERR_REASON(CMS_R_NO_MATCHING_SIGNATURE) ,"no matching signature"},
+{ERR_REASON(CMS_R_NO_MSGSIGDIGEST)       ,"no msgsigdigest"},
+{ERR_REASON(CMS_R_NO_PASSWORD)           ,"no password"},
+{ERR_REASON(CMS_R_NO_PRIVATE_KEY)        ,"no private key"},
+{ERR_REASON(CMS_R_NO_PUBLIC_KEY)         ,"no public key"},
+{ERR_REASON(CMS_R_NO_RECEIPT_REQUEST)    ,"no receipt request"},
+{ERR_REASON(CMS_R_NO_SIGNERS)            ,"no signers"},
+{ERR_REASON(CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
+{ERR_REASON(CMS_R_RECEIPT_DECODE_ERROR)  ,"receipt decode error"},
+{ERR_REASON(CMS_R_RECIPIENT_ERROR)       ,"recipient error"},
+{ERR_REASON(CMS_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"},
+{ERR_REASON(CMS_R_SIGNFINAL_ERROR)       ,"signfinal error"},
+{ERR_REASON(CMS_R_SMIME_TEXT_ERROR)      ,"smime text error"},
+{ERR_REASON(CMS_R_STORE_INIT_ERROR)      ,"store init error"},
+{ERR_REASON(CMS_R_TYPE_NOT_COMPRESSED_DATA),"type not compressed data"},
+{ERR_REASON(CMS_R_TYPE_NOT_DATA)         ,"type not data"},
+{ERR_REASON(CMS_R_TYPE_NOT_DIGESTED_DATA),"type not digested data"},
+{ERR_REASON(CMS_R_TYPE_NOT_ENCRYPTED_DATA),"type not encrypted data"},
+{ERR_REASON(CMS_R_TYPE_NOT_ENVELOPED_DATA),"type not enveloped data"},
+{ERR_REASON(CMS_R_UNABLE_TO_FINALIZE_CONTEXT),"unable to finalize context"},
+{ERR_REASON(CMS_R_UNKNOWN_CIPHER)        ,"unknown cipher"},
+{ERR_REASON(CMS_R_UNKNOWN_DIGEST_ALGORIHM),"unknown digest algorihm"},
+{ERR_REASON(CMS_R_UNKNOWN_ID)            ,"unknown id"},
+{ERR_REASON(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM),"unsupported compression algorithm"},
+{ERR_REASON(CMS_R_UNSUPPORTED_CONTENT_TYPE),"unsupported content type"},
+{ERR_REASON(CMS_R_UNSUPPORTED_KEK_ALGORITHM),"unsupported kek algorithm"},
+{ERR_REASON(CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM),"unsupported key encryption algorithm"},
+{ERR_REASON(CMS_R_UNSUPPORTED_RECIPIENT_TYPE),"unsupported recipient type"},
+{ERR_REASON(CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE),"unsupported recpientinfo type"},
+{ERR_REASON(CMS_R_UNSUPPORTED_TYPE)      ,"unsupported type"},
+{ERR_REASON(CMS_R_UNWRAP_ERROR)          ,"unwrap error"},
+{ERR_REASON(CMS_R_UNWRAP_FAILURE)        ,"unwrap failure"},
+{ERR_REASON(CMS_R_VERIFICATION_FAILURE)  ,"verification failure"},
+{ERR_REASON(CMS_R_WRAP_ERROR)            ,"wrap error"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_CMS_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(CMS_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,CMS_str_functs);
+		ERR_load_strings(0,CMS_str_reasons);
+		}
+#endif
+	}
diff --git a/crypto/cms/cms_ess.c b/crypto/cms/cms_ess.c
new file mode 100644
index 0000000..90c0b82
--- /dev/null
+++ b/crypto/cms/cms_ess.c
@@ -0,0 +1,420 @@
+/* crypto/cms/cms_ess.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include "cms_lcl.h"
+
+DECLARE_ASN1_ITEM(CMS_ReceiptRequest)
+DECLARE_ASN1_ITEM(CMS_Receipt)
+
+IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest)
+
+/* ESS services: for now just Signed Receipt related */
+
+int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr)
+	{
+	ASN1_STRING *str;
+	CMS_ReceiptRequest *rr = NULL;
+	if (prr)
+		*prr = NULL;
+	str = CMS_signed_get0_data_by_OBJ(si,
+				OBJ_nid2obj(NID_id_smime_aa_receiptRequest),
+					-3, V_ASN1_SEQUENCE);
+	if (!str)
+		return 0;
+
+	rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest));
+	if (!rr)
+		return -1;
+	if (prr)
+		*prr = rr;
+	else
+		CMS_ReceiptRequest_free(rr);
+	return 1;
+	}
+
+CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
+				int allorfirst,
+				STACK_OF(GENERAL_NAMES) *receiptList,
+				STACK_OF(GENERAL_NAMES) *receiptsTo)
+	{
+	CMS_ReceiptRequest *rr = NULL;
+
+	rr = CMS_ReceiptRequest_new();
+	if (!rr)
+		goto merr;
+	if (id)
+		ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen);
+	else
+		{
+		if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32))
+			goto merr;
+		if (RAND_pseudo_bytes(rr->signedContentIdentifier->data, 32) 
+					<= 0)
+			goto err;
+		}
+
+	sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free);
+	rr->receiptsTo = receiptsTo;
+
+	if (receiptList)
+		{
+		rr->receiptsFrom->type = 1;
+		rr->receiptsFrom->d.receiptList = receiptList;
+		}
+	else
+		{
+		rr->receiptsFrom->type = 0;
+		rr->receiptsFrom->d.allOrFirstTier = allorfirst;
+		}
+
+	return rr;
+
+	merr:
+	CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE);
+
+	err:
+	if (rr)
+		CMS_ReceiptRequest_free(rr);
+
+	return NULL;
+	
+	}
+
+int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr)
+	{
+	unsigned char *rrder = NULL;
+	int rrderlen, r = 0;
+
+	rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder);
+	if (rrderlen < 0)
+		goto merr;
+
+	if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest,
+					V_ASN1_SEQUENCE, rrder, rrderlen))
+		goto merr;
+
+	r = 1;
+
+	merr:
+	if (!r)
+		CMSerr(CMS_F_CMS_ADD1_RECEIPTREQUEST, ERR_R_MALLOC_FAILURE);
+
+	if (rrder)
+		OPENSSL_free(rrder);
+
+	return r;
+	
+	}
+
+void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
+					ASN1_STRING **pcid,
+					int *pallorfirst,
+					STACK_OF(GENERAL_NAMES) **plist,
+					STACK_OF(GENERAL_NAMES) **prto)
+	{
+	if (pcid)
+		*pcid = rr->signedContentIdentifier;
+	if (rr->receiptsFrom->type == 0)
+		{
+		if (pallorfirst)
+			*pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier;
+		if (plist)
+			*plist = NULL;
+		}
+	else
+		{
+		if (pallorfirst)
+			*pallorfirst = -1;
+		if (plist)
+			*plist = rr->receiptsFrom->d.receiptList;
+		}
+	if (prto)
+		*prto = rr->receiptsTo;
+	}
+
+/* Digest a SignerInfo structure for msgSigDigest attribute processing */
+
+static int cms_msgSigDigest(CMS_SignerInfo *si,
+				unsigned char *dig, unsigned int *diglen)
+	{
+	const EVP_MD *md;
+	md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
+	if (md == NULL)
+		return 0;
+	if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md,
+						si->signedAttrs, dig, diglen))
+		return 0;
+	return 1;
+	}
+
+/* Add a msgSigDigest attribute to a SignerInfo */
+
+int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src)
+	{
+	unsigned char dig[EVP_MAX_MD_SIZE];
+	unsigned int diglen;
+	if (!cms_msgSigDigest(src, dig, &diglen))
+		{
+		CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR);
+		return 0;
+		}
+	if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest,
+					V_ASN1_OCTET_STRING, dig, diglen))
+		{
+		CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+	return 1;
+	}
+
+/* Verify signed receipt after it has already passed normal CMS verify */
+
+int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms)
+	{
+	int r = 0, i;
+	CMS_ReceiptRequest *rr = NULL;
+	CMS_Receipt *rct = NULL;
+	STACK_OF(CMS_SignerInfo) *sis, *osis;
+	CMS_SignerInfo *si, *osi = NULL;
+	ASN1_OCTET_STRING *msig, **pcont;
+	ASN1_OBJECT *octype;
+	unsigned char dig[EVP_MAX_MD_SIZE];
+	unsigned int diglen;
+
+	/* Get SignerInfos, also checks SignedData content type */
+	osis = CMS_get0_SignerInfos(req_cms);
+	sis = CMS_get0_SignerInfos(cms);
+	if (!osis || !sis)
+		goto err;
+
+	if (sk_CMS_SignerInfo_num(sis) != 1)
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NEED_ONE_SIGNER);
+		goto err;
+		}
+
+	/* Check receipt content type */
+	if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt)
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NOT_A_SIGNED_RECEIPT);
+		goto err;
+		}
+
+	/* Extract and decode receipt content */
+	pcont = CMS_get0_content(cms);
+	if (!pcont || !*pcont)
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT);
+		goto err;
+		}
+
+	rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt));
+
+	if (!rct)	
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_RECEIPT_DECODE_ERROR);
+		goto err;
+		}
+
+	/* Locate original request */
+
+	for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++)
+		{
+		osi = sk_CMS_SignerInfo_value(osis, i);
+		if (!ASN1_STRING_cmp(osi->signature,
+					rct->originatorSignatureValue))
+			break;
+		}
+
+	if (i == sk_CMS_SignerInfo_num(osis))
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MATCHING_SIGNATURE);
+		goto err;
+		}
+
+	si = sk_CMS_SignerInfo_value(sis, 0);
+
+	/* Get msgSigDigest value and compare */
+
+	msig = CMS_signed_get0_data_by_OBJ(si,
+				OBJ_nid2obj(NID_id_smime_aa_msgSigDigest),
+					-3, V_ASN1_OCTET_STRING);
+
+	if (!msig)
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MSGSIGDIGEST);
+		goto err;
+		}
+
+	if (!cms_msgSigDigest(osi, dig, &diglen))
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_ERROR);
+		goto err;
+		}
+
+	if (diglen != (unsigned int)msig->length)
+			{
+			CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
+				CMS_R_MSGSIGDIGEST_WRONG_LENGTH);
+			goto err;
+			}
+
+	if (memcmp(dig, msig->data, diglen))
+			{
+			CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
+				CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE);
+			goto err;
+			}
+
+	/* Compare content types */
+
+	octype = CMS_signed_get0_data_by_OBJ(osi,
+				OBJ_nid2obj(NID_pkcs9_contentType),
+					-3, V_ASN1_OBJECT);
+	if (!octype)
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT_TYPE);
+		goto err;
+		}
+
+	/* Compare details in receipt request */
+
+	if (OBJ_cmp(octype, rct->contentType))
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENT_TYPE_MISMATCH);
+		goto err;
+		}
+
+	/* Get original receipt request details */
+
+	if (CMS_get1_ReceiptRequest(osi, &rr) <= 0)
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST);
+		goto err;
+		}
+
+	if (ASN1_STRING_cmp(rr->signedContentIdentifier,
+					rct->signedContentIdentifier))
+		{
+		CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
+					CMS_R_CONTENTIDENTIFIER_MISMATCH);
+		goto err;
+		}
+
+	r = 1;
+
+	err:
+	if (rr)
+		CMS_ReceiptRequest_free(rr);
+	if (rct)
+		M_ASN1_free_of(rct, CMS_Receipt);
+
+	return r;
+
+	}
+
+/* Encode a Receipt into an OCTET STRING read for including into content of
+ * a SignedData ContentInfo.
+ */
+
+ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si)
+	{
+	CMS_Receipt rct;
+	CMS_ReceiptRequest *rr = NULL;
+	ASN1_OBJECT *ctype;
+	ASN1_OCTET_STRING *os = NULL;
+
+	/* Get original receipt request */
+
+	/* Get original receipt request details */
+
+	if (CMS_get1_ReceiptRequest(si, &rr) <= 0)
+		{
+		CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST);
+		goto err;
+		}
+
+	/* Get original content type */
+
+	ctype = CMS_signed_get0_data_by_OBJ(si,
+				OBJ_nid2obj(NID_pkcs9_contentType),
+					-3, V_ASN1_OBJECT);
+	if (!ctype)
+		{
+		CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_CONTENT_TYPE);
+		goto err;
+		}
+
+	rct.version = 1;
+	rct.contentType = ctype;
+	rct.signedContentIdentifier = rr->signedContentIdentifier;
+	rct.originatorSignatureValue = si->signature;
+
+	os = ASN1_item_pack(&rct, ASN1_ITEM_rptr(CMS_Receipt), NULL);
+
+	err:
+	if (rr)
+		CMS_ReceiptRequest_free(rr);
+
+	return os;
+
+	}
+
+
diff --git a/crypto/cms/cms_io.c b/crypto/cms/cms_io.c
new file mode 100644
index 0000000..1cb0264
--- /dev/null
+++ b/crypto/cms/cms_io.c
@@ -0,0 +1,133 @@
+/* crypto/cms/cms_io.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include "cms.h"
+#include "cms_lcl.h"
+
+int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms)
+	{
+	ASN1_OCTET_STRING **pos;
+	pos = CMS_get0_content(cms);
+	if (!pos)
+		return 0;
+	if (!*pos)
+		*pos = ASN1_OCTET_STRING_new();
+	if (*pos)
+		{
+		(*pos)->flags |= ASN1_STRING_FLAG_NDEF;
+		(*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
+		*boundary = &(*pos)->data;
+		return 1;
+		}
+	CMSerr(CMS_F_CMS_STREAM, ERR_R_MALLOC_FAILURE);
+	return 0;
+	}
+
+CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms)
+	{
+	return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
+	}
+
+int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms)
+	{
+	return ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
+	}
+
+IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo)
+
+BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms) 
+	{
+	return BIO_new_NDEF(out, (ASN1_VALUE *)cms,
+				ASN1_ITEM_rptr(CMS_ContentInfo));
+	}
+
+/* CMS wrappers round generalised stream and MIME routines */
+
+int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags)
+	{
+	return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)cms, in, flags,
+					ASN1_ITEM_rptr(CMS_ContentInfo));
+	}
+
+int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags)
+	{
+	return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *) cms, in, flags,
+					"CMS",
+					ASN1_ITEM_rptr(CMS_ContentInfo));
+	}
+
+int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags)
+	{
+	STACK_OF(X509_ALGOR) *mdalgs;
+	int ctype_nid = OBJ_obj2nid(cms->contentType);
+	int econt_nid = OBJ_obj2nid(CMS_get0_eContentType(cms));
+	if (ctype_nid == NID_pkcs7_signed)
+		mdalgs = cms->d.signedData->digestAlgorithms;
+	else
+		mdalgs = NULL;
+
+	return SMIME_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags,
+					ctype_nid, econt_nid, mdalgs,
+					ASN1_ITEM_rptr(CMS_ContentInfo));	
+	}
+
+CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont)
+	{
+	return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont,
+					ASN1_ITEM_rptr(CMS_ContentInfo));
+	}
+
diff --git a/crypto/cms/cms_lcl.h b/crypto/cms/cms_lcl.h
new file mode 100644
index 0000000..a9f9730
--- /dev/null
+++ b/crypto/cms/cms_lcl.h
@@ -0,0 +1,473 @@
+/* crypto/cms/cms_lcl.h */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#ifndef HEADER_CMS_LCL_H
+#define HEADER_CMS_LCL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <openssl/x509.h>
+
+/* Cryptographic message syntax (CMS) structures: taken
+ * from RFC3852
+ */
+
+/* Forward references */
+
+typedef struct CMS_IssuerAndSerialNumber_st CMS_IssuerAndSerialNumber;
+typedef struct CMS_EncapsulatedContentInfo_st CMS_EncapsulatedContentInfo;
+typedef struct CMS_SignerIdentifier_st CMS_SignerIdentifier;
+typedef struct CMS_SignedData_st CMS_SignedData;
+typedef struct CMS_OtherRevocationInfoFormat_st CMS_OtherRevocationInfoFormat;
+typedef struct CMS_OriginatorInfo_st CMS_OriginatorInfo;
+typedef struct CMS_EncryptedContentInfo_st CMS_EncryptedContentInfo;
+typedef struct CMS_EnvelopedData_st CMS_EnvelopedData;
+typedef struct CMS_DigestedData_st CMS_DigestedData;
+typedef struct CMS_EncryptedData_st CMS_EncryptedData;
+typedef struct CMS_AuthenticatedData_st CMS_AuthenticatedData;
+typedef struct CMS_CompressedData_st CMS_CompressedData;
+typedef struct CMS_OtherCertificateFormat_st CMS_OtherCertificateFormat;
+typedef struct CMS_KeyTransRecipientInfo_st CMS_KeyTransRecipientInfo;
+typedef struct CMS_OriginatorPublicKey_st CMS_OriginatorPublicKey;
+typedef struct CMS_OriginatorIdentifierOrKey_st CMS_OriginatorIdentifierOrKey;
+typedef struct CMS_KeyAgreeRecipientInfo_st CMS_KeyAgreeRecipientInfo;
+typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute;
+typedef struct CMS_RecipientKeyIdentifier_st CMS_RecipientKeyIdentifier;
+typedef struct CMS_KeyAgreeRecipientIdentifier_st CMS_KeyAgreeRecipientIdentifier;
+typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey;
+typedef struct CMS_KEKIdentifier_st CMS_KEKIdentifier;
+typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo;
+typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo;
+typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo;
+typedef struct CMS_ReceiptsFrom_st CMS_ReceiptsFrom;
+
+struct CMS_ContentInfo_st
+	{
+	ASN1_OBJECT *contentType;
+	union	{
+		ASN1_OCTET_STRING *data;
+		CMS_SignedData *signedData;
+		CMS_EnvelopedData *envelopedData;
+		CMS_DigestedData *digestedData;
+		CMS_EncryptedData *encryptedData;
+		CMS_AuthenticatedData *authenticatedData;
+		CMS_CompressedData *compressedData;
+		ASN1_TYPE *other;
+		/* Other types ... */
+		void *otherData;
+		} d;
+	};
+
+struct CMS_SignedData_st
+	{
+	long version;
+	STACK_OF(X509_ALGOR) *digestAlgorithms;
+	CMS_EncapsulatedContentInfo *encapContentInfo;
+	STACK_OF(CMS_CertificateChoices) *certificates;
+	STACK_OF(CMS_RevocationInfoChoice) *crls;
+	STACK_OF(CMS_SignerInfo) *signerInfos;
+	};
+ 
+struct CMS_EncapsulatedContentInfo_st
+	{
+	ASN1_OBJECT *eContentType;
+	ASN1_OCTET_STRING *eContent;
+	/* Set to 1 if incomplete structure only part set up */
+	int partial;
+	};
+
+struct CMS_SignerInfo_st
+	{
+	long version;
+	CMS_SignerIdentifier *sid;
+	X509_ALGOR *digestAlgorithm;
+	STACK_OF(X509_ATTRIBUTE) *signedAttrs;
+	X509_ALGOR *signatureAlgorithm;
+	ASN1_OCTET_STRING *signature;
+	STACK_OF(X509_ATTRIBUTE) *unsignedAttrs;
+	/* Signing certificate and key */
+	X509 *signer;
+	EVP_PKEY *pkey;
+	};
+
+struct CMS_SignerIdentifier_st
+	{
+	int type;
+	union	{
+		CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
+		ASN1_OCTET_STRING *subjectKeyIdentifier;
+		} d;
+	};
+
+struct CMS_EnvelopedData_st
+	{
+	long version;
+	CMS_OriginatorInfo *originatorInfo;
+	STACK_OF(CMS_RecipientInfo) *recipientInfos;
+	CMS_EncryptedContentInfo *encryptedContentInfo;
+	STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs;
+	};
+
+struct CMS_OriginatorInfo_st
+	{
+	STACK_OF(CMS_CertificateChoices) *certificates;
+	STACK_OF(CMS_RevocationInfoChoice) *crls;
+	};
+
+struct CMS_EncryptedContentInfo_st
+	{
+	ASN1_OBJECT *contentType;
+	X509_ALGOR *contentEncryptionAlgorithm;
+	ASN1_OCTET_STRING *encryptedContent;
+	/* Content encryption algorithm and key */
+	const EVP_CIPHER *cipher;
+	unsigned char *key;
+	size_t keylen;
+	/* Set to 1 if we are debugging decrypt and don't fake keys for MMA */
+	int debug;
+	};
+
+struct CMS_RecipientInfo_st
+	{
+ 	int type;
+ 	union	{
+  	 	CMS_KeyTransRecipientInfo *ktri;
+   		CMS_KeyAgreeRecipientInfo *kari;
+   		CMS_KEKRecipientInfo *kekri;
+		CMS_PasswordRecipientInfo *pwri;
+		CMS_OtherRecipientInfo *ori;
+		} d;
+	};
+
+typedef CMS_SignerIdentifier CMS_RecipientIdentifier;
+
+struct CMS_KeyTransRecipientInfo_st
+	{
+	long version;
+	CMS_RecipientIdentifier *rid;
+	X509_ALGOR *keyEncryptionAlgorithm;
+	ASN1_OCTET_STRING *encryptedKey;
+	/* Recipient Key and cert */
+	X509 *recip;
+	EVP_PKEY *pkey;
+	};
+
+struct CMS_KeyAgreeRecipientInfo_st
+	{
+	long version;
+	CMS_OriginatorIdentifierOrKey *originator;
+	ASN1_OCTET_STRING *ukm;
+ 	X509_ALGOR *keyEncryptionAlgorithm;
+	STACK_OF(CMS_RecipientEncryptedKey) *recipientEncryptedKeys;
+	};
+
+struct CMS_OriginatorIdentifierOrKey_st
+	{
+	int type;
+	union	{
+		CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
+		ASN1_OCTET_STRING *subjectKeyIdentifier;
+		CMS_OriginatorPublicKey *originatorKey;
+		} d;
+	};
+
+struct CMS_OriginatorPublicKey_st
+	{
+	X509_ALGOR *algorithm;
+	ASN1_BIT_STRING *publicKey;
+	};
+
+struct CMS_RecipientEncryptedKey_st
+	{
+ 	CMS_KeyAgreeRecipientIdentifier *rid;
+ 	ASN1_OCTET_STRING *encryptedKey;
+	};
+
+struct CMS_KeyAgreeRecipientIdentifier_st
+	{
+	int type;
+	union	{
+		CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
+		CMS_RecipientKeyIdentifier *rKeyId;
+		} d;
+	};
+
+struct CMS_RecipientKeyIdentifier_st
+	{
+ 	ASN1_OCTET_STRING *subjectKeyIdentifier;
+ 	ASN1_GENERALIZEDTIME *date;
+ 	CMS_OtherKeyAttribute *other;
+	};
+
+struct CMS_KEKRecipientInfo_st
+	{
+ 	long version;
+ 	CMS_KEKIdentifier *kekid;
+ 	X509_ALGOR *keyEncryptionAlgorithm;
+ 	ASN1_OCTET_STRING *encryptedKey;
+	/* Extra info: symmetric key to use */
+	unsigned char *key;
+	size_t keylen;
+	};
+
+struct CMS_KEKIdentifier_st
+	{
+ 	ASN1_OCTET_STRING *keyIdentifier;
+ 	ASN1_GENERALIZEDTIME *date;
+ 	CMS_OtherKeyAttribute *other;
+	};
+
+struct CMS_PasswordRecipientInfo_st
+	{
+ 	long version;
+ 	X509_ALGOR *keyDerivationAlgorithm;
+ 	X509_ALGOR *keyEncryptionAlgorithm;
+ 	ASN1_OCTET_STRING *encryptedKey;
+	/* Extra info: password to use */
+	unsigned char *pass;
+	size_t passlen;
+	};
+
+struct CMS_OtherRecipientInfo_st
+	{
+ 	ASN1_OBJECT *oriType;
+ 	ASN1_TYPE *oriValue;
+	};
+
+struct CMS_DigestedData_st
+	{
+	long version;
+	X509_ALGOR *digestAlgorithm;
+	CMS_EncapsulatedContentInfo *encapContentInfo;
+	ASN1_OCTET_STRING *digest;
+	};
+
+struct CMS_EncryptedData_st
+	{
+	long version;
+	CMS_EncryptedContentInfo *encryptedContentInfo;
+	STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs;
+	};
+
+struct CMS_AuthenticatedData_st
+	{
+	long version;
+	CMS_OriginatorInfo *originatorInfo;
+	STACK_OF(CMS_RecipientInfo) *recipientInfos;
+	X509_ALGOR *macAlgorithm;
+	X509_ALGOR *digestAlgorithm;
+	CMS_EncapsulatedContentInfo *encapContentInfo;
+	STACK_OF(X509_ATTRIBUTE) *authAttrs;
+	ASN1_OCTET_STRING *mac;
+	STACK_OF(X509_ATTRIBUTE) *unauthAttrs;
+	};
+
+struct CMS_CompressedData_st
+	{
+	long version;
+	X509_ALGOR *compressionAlgorithm;
+	STACK_OF(CMS_RecipientInfo) *recipientInfos;
+	CMS_EncapsulatedContentInfo *encapContentInfo;
+	};
+
+struct CMS_RevocationInfoChoice_st
+	{
+	int type;
+	union	{
+		X509_CRL *crl;
+		CMS_OtherRevocationInfoFormat *other;
+		} d;
+	};
+
+#define CMS_REVCHOICE_CRL		0
+#define CMS_REVCHOICE_OTHER		1
+
+struct CMS_OtherRevocationInfoFormat_st
+	{
+	ASN1_OBJECT *otherRevInfoFormat;
+ 	ASN1_TYPE *otherRevInfo;
+	};
+
+struct CMS_CertificateChoices
+	{
+	int type;
+		union {
+		X509 *certificate;
+		ASN1_STRING *extendedCertificate;	/* Obsolete */
+		ASN1_STRING *v1AttrCert;	/* Left encoded for now */
+		ASN1_STRING *v2AttrCert;	/* Left encoded for now */
+		CMS_OtherCertificateFormat *other;
+		} d;
+	};
+
+#define CMS_CERTCHOICE_CERT		0
+#define CMS_CERTCHOICE_EXCERT		1
+#define CMS_CERTCHOICE_V1ACERT		2
+#define CMS_CERTCHOICE_V2ACERT		3
+#define CMS_CERTCHOICE_OTHER		4
+
+struct CMS_OtherCertificateFormat_st
+	{
+	ASN1_OBJECT *otherCertFormat;
+ 	ASN1_TYPE *otherCert;
+	};
+
+/* This is also defined in pkcs7.h but we duplicate it
+ * to allow the CMS code to be independent of PKCS#7
+ */
+
+struct CMS_IssuerAndSerialNumber_st
+	{
+	X509_NAME *issuer;
+	ASN1_INTEGER *serialNumber;
+	};
+
+struct CMS_OtherKeyAttribute_st
+	{
+	ASN1_OBJECT *keyAttrId;
+ 	ASN1_TYPE *keyAttr;
+	};
+
+/* ESS structures */
+
+#ifdef HEADER_X509V3_H
+
+struct CMS_ReceiptRequest_st
+	{
+	ASN1_OCTET_STRING *signedContentIdentifier;
+	CMS_ReceiptsFrom *receiptsFrom;
+	STACK_OF(GENERAL_NAMES) *receiptsTo;
+	};
+
+
+struct CMS_ReceiptsFrom_st
+	{
+	int type;
+	union
+		{
+		long allOrFirstTier;
+		STACK_OF(GENERAL_NAMES) *receiptList;
+		} d;
+	};
+#endif
+
+struct CMS_Receipt_st
+	{
+	long version;
+	ASN1_OBJECT *contentType;
+	ASN1_OCTET_STRING *signedContentIdentifier;
+	ASN1_OCTET_STRING *originatorSignatureValue;
+	};
+
+DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
+DECLARE_ASN1_ITEM(CMS_SignerInfo)
+DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber)
+DECLARE_ASN1_ITEM(CMS_Attributes_Sign)
+DECLARE_ASN1_ITEM(CMS_Attributes_Verify)
+DECLARE_ASN1_ITEM(CMS_RecipientInfo)
+DECLARE_ASN1_ITEM(CMS_PasswordRecipientInfo)
+DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber)
+
+#define CMS_SIGNERINFO_ISSUER_SERIAL	0
+#define CMS_SIGNERINFO_KEYIDENTIFIER	1
+
+#define CMS_RECIPINFO_ISSUER_SERIAL	0
+#define CMS_RECIPINFO_KEYIDENTIFIER	1
+
+BIO *cms_content_bio(CMS_ContentInfo *cms);
+
+CMS_ContentInfo *cms_Data_create(void);
+
+CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md);
+BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms);
+int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify);
+
+BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms);
+int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain);
+int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type);
+int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
+					ASN1_OCTET_STRING **keyid,
+					X509_NAME **issuer, ASN1_INTEGER **sno);
+int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert);
+
+CMS_ContentInfo *cms_CompressedData_create(int comp_nid);
+BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms);
+
+void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md);
+BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm);
+int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
+					X509_ALGOR *mdalg);
+
+BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec);
+BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms);
+int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, 
+				const EVP_CIPHER *cipher,
+				const unsigned char *key, size_t keylen);
+
+int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms);
+int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src);
+ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si);
+
+BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
+CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms);
+
+/* PWRI routines */
+int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
+							int en_de);
+	
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/crypto/cms/cms_lib.c b/crypto/cms/cms_lib.c
new file mode 100644
index 0000000..b62d1bf
--- /dev/null
+++ b/crypto/cms/cms_lib.c
@@ -0,0 +1,624 @@
+/* crypto/cms/cms_lib.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+#include "cms.h"
+#include "cms_lcl.h"
+
+IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo)
+IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
+
+DECLARE_ASN1_ITEM(CMS_CertificateChoices)
+DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice)
+DECLARE_STACK_OF(CMS_CertificateChoices)
+DECLARE_STACK_OF(CMS_RevocationInfoChoice)
+
+const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms)
+	{
+	return cms->contentType;
+	}
+
+CMS_ContentInfo *cms_Data_create(void)
+	{
+	CMS_ContentInfo *cms;
+	cms = CMS_ContentInfo_new();
+	if (cms)
+		{
+		cms->contentType = OBJ_nid2obj(NID_pkcs7_data);
+		/* Never detached */
+		CMS_set_detached(cms, 0);
+		}
+	return cms;
+	}
+
+BIO *cms_content_bio(CMS_ContentInfo *cms)
+	{
+	ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
+	if (!pos)
+		return NULL;
+	/* If content detached data goes nowhere: create NULL BIO */
+	if (!*pos)
+		return BIO_new(BIO_s_null());
+	/* If content not detached and created return memory BIO
+	 */
+	if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT))
+		return BIO_new(BIO_s_mem());
+	/* Else content was read in: return read only BIO for it */
+	return BIO_new_mem_buf((*pos)->data, (*pos)->length);
+	}
+
+BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
+	{
+	BIO *cmsbio, *cont;
+	if (icont)
+		cont = icont;
+	else
+		cont = cms_content_bio(cms);
+	if (!cont)
+		{
+		CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT);
+		return NULL;
+		}
+	switch (OBJ_obj2nid(cms->contentType))
+		{
+
+		case NID_pkcs7_data:
+		return cont;
+
+		case NID_pkcs7_signed:
+		cmsbio = cms_SignedData_init_bio(cms);
+		break;
+
+		case NID_pkcs7_digest:
+		cmsbio = cms_DigestedData_init_bio(cms);
+		break;
+#ifdef ZLIB
+		case NID_id_smime_ct_compressedData:
+		cmsbio = cms_CompressedData_init_bio(cms);
+		break;
+#endif
+
+		case NID_pkcs7_encrypted:
+		cmsbio = cms_EncryptedData_init_bio(cms);
+		break;
+
+		case NID_pkcs7_enveloped:
+		cmsbio = cms_EnvelopedData_init_bio(cms);
+		break;
+
+		default:
+		CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE);
+		return NULL;
+		}
+
+	if (cmsbio)
+		return BIO_push(cmsbio, cont);
+
+	if (!icont)
+		BIO_free(cont);
+	return NULL;
+
+	}
+
+int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
+	{
+	ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
+	if (!pos)
+		return 0;
+	/* If ebmedded content find memory BIO and set content */
+	if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT))
+		{
+		BIO *mbio;
+		unsigned char *cont;
+		long contlen;
+		mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM);
+		if (!mbio)
+			{
+			CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND);
+			return 0;
+			}
+		contlen = BIO_get_mem_data(mbio, &cont);
+		/* Set bio as read only so its content can't be clobbered */
+		BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY);
+		BIO_set_mem_eof_return(mbio, 0);
+		ASN1_STRING_set0(*pos, cont, contlen);
+		(*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
+		}
+
+	switch (OBJ_obj2nid(cms->contentType))
+		{
+
+		case NID_pkcs7_data:
+		case NID_pkcs7_enveloped:
+		case NID_pkcs7_encrypted:
+		case NID_id_smime_ct_compressedData:
+		/* Nothing to do */
+		return 1;
+
+		case NID_pkcs7_signed:
+		return cms_SignedData_final(cms, cmsbio);
+
+		case NID_pkcs7_digest:
+		return cms_DigestedData_do_final(cms, cmsbio, 0);
+
+		default:
+		CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE);
+		return 0;
+		}
+	}
+
+/* Return an OCTET STRING pointer to content. This allows it to
+ * be accessed or set later.
+ */
+
+ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms)
+	{
+	switch (OBJ_obj2nid(cms->contentType))
+		{
+
+		case NID_pkcs7_data:
+		return &cms->d.data;
+
+		case NID_pkcs7_signed:
+		return &cms->d.signedData->encapContentInfo->eContent;
+
+		case NID_pkcs7_enveloped:
+		return &cms->d.envelopedData->encryptedContentInfo->encryptedContent;
+
+		case NID_pkcs7_digest:
+		return &cms->d.digestedData->encapContentInfo->eContent;
+
+		case NID_pkcs7_encrypted:
+		return &cms->d.encryptedData->encryptedContentInfo->encryptedContent;
+
+		case NID_id_smime_ct_authData:
+		return &cms->d.authenticatedData->encapContentInfo->eContent;
+
+		case NID_id_smime_ct_compressedData:
+		return &cms->d.compressedData->encapContentInfo->eContent;
+
+		default:
+		if (cms->d.other->type == V_ASN1_OCTET_STRING)
+			return &cms->d.other->value.octet_string;
+		CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE);
+		return NULL;
+
+		}
+	}
+
+/* Return an ASN1_OBJECT pointer to content type. This allows it to
+ * be accessed or set later.
+ */
+
+static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms)
+	{
+	switch (OBJ_obj2nid(cms->contentType))
+		{
+
+		case NID_pkcs7_signed:
+		return &cms->d.signedData->encapContentInfo->eContentType;
+
+		case NID_pkcs7_enveloped:
+		return &cms->d.envelopedData->encryptedContentInfo->contentType;
+
+		case NID_pkcs7_digest:
+		return &cms->d.digestedData->encapContentInfo->eContentType;
+
+		case NID_pkcs7_encrypted:
+		return &cms->d.encryptedData->encryptedContentInfo->contentType;
+
+		case NID_id_smime_ct_authData:
+		return &cms->d.authenticatedData->encapContentInfo->eContentType;
+
+		case NID_id_smime_ct_compressedData:
+		return &cms->d.compressedData->encapContentInfo->eContentType;
+
+		default:
+		CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE,
+					CMS_R_UNSUPPORTED_CONTENT_TYPE);
+		return NULL;
+
+		}
+	}
+
+const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms)
+	{
+	ASN1_OBJECT **petype;
+	petype = cms_get0_econtent_type(cms);
+	if (petype)
+		return *petype;
+	return NULL;
+	}
+
+int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid)
+	{
+	ASN1_OBJECT **petype, *etype;
+	petype = cms_get0_econtent_type(cms);
+	if (!petype)
+		return 0;
+	if (!oid)
+		return 1;
+	etype = OBJ_dup(oid);
+	if (!etype)
+		return 0;
+	ASN1_OBJECT_free(*petype);
+	*petype = etype;
+	return 1;
+	}
+
+int CMS_is_detached(CMS_ContentInfo *cms)
+	{
+	ASN1_OCTET_STRING **pos;
+	pos = CMS_get0_content(cms);
+	if (!pos)
+		return -1;
+	if (*pos)
+		return 0;
+	return 1;
+	}
+
+int CMS_set_detached(CMS_ContentInfo *cms, int detached)
+	{
+	ASN1_OCTET_STRING **pos;
+	pos = CMS_get0_content(cms);
+	if (!pos)
+		return 0;
+	if (detached)
+		{
+		if (*pos)
+			{
+			ASN1_OCTET_STRING_free(*pos);
+			*pos = NULL;
+			}
+		return 1;
+		}
+	if (!*pos)
+		*pos = ASN1_OCTET_STRING_new();
+	if (*pos)
+		{
+		/* NB: special flag to show content is created and not
+		 * read in.
+		 */
+		(*pos)->flags |= ASN1_STRING_FLAG_CONT;
+		return 1;
+		}
+	CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE);
+	return 0;
+	}
+
+/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
+
+void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md)
+	{
+	int param_type;
+
+	if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
+		param_type = V_ASN1_UNDEF;
+	else
+		param_type = V_ASN1_NULL;
+
+	X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
+
+	}
+
+/* Create a digest BIO from an X509_ALGOR structure */
+
+BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm)
+	{
+	BIO *mdbio = NULL;
+	ASN1_OBJECT *digestoid;
+	const EVP_MD *digest;
+	X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm);
+	digest = EVP_get_digestbyobj(digestoid);
+	if (!digest)
+		{
+		CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
+				CMS_R_UNKNOWN_DIGEST_ALGORIHM);
+		goto err;	
+		}
+	mdbio = BIO_new(BIO_f_md());
+	if (!mdbio || !BIO_set_md(mdbio, digest))
+		{
+		CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
+				CMS_R_MD_BIO_INIT_ERROR);
+		goto err;	
+		}
+	return mdbio;
+	err:
+	if (mdbio)
+		BIO_free(mdbio);
+	return NULL;
+	}
+
+/* Locate a message digest content from a BIO chain based on SignerInfo */
+
+int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
+					X509_ALGOR *mdalg)
+	{
+	int nid;
+	ASN1_OBJECT *mdoid;
+	X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg);
+	nid = OBJ_obj2nid(mdoid);
+	/* Look for digest type to match signature */
+	for (;;)
+		{
+		EVP_MD_CTX *mtmp;
+		chain = BIO_find_type(chain, BIO_TYPE_MD);
+		if (chain == NULL)
+			{
+			CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX,
+						CMS_R_NO_MATCHING_DIGEST);
+			return 0;
+			}
+		BIO_get_md_ctx(chain, &mtmp);
+		if (EVP_MD_CTX_type(mtmp) == nid
+		/* Workaround for broken implementations that use signature
+		 * 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);
+		}
+	}
+
+static STACK_OF(CMS_CertificateChoices) **cms_get0_certificate_choices(CMS_ContentInfo *cms)
+	{
+	switch (OBJ_obj2nid(cms->contentType))
+		{
+
+		case NID_pkcs7_signed:
+		return &cms->d.signedData->certificates;
+
+		case NID_pkcs7_enveloped:
+		return &cms->d.envelopedData->originatorInfo->certificates;
+
+		default:
+		CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES,
+					CMS_R_UNSUPPORTED_CONTENT_TYPE);
+		return NULL;
+
+		}
+	}
+
+CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms)
+	{
+	STACK_OF(CMS_CertificateChoices) **pcerts;
+	CMS_CertificateChoices *cch;
+	pcerts = cms_get0_certificate_choices(cms);
+	if (!pcerts)
+		return NULL;
+	if (!*pcerts)
+		*pcerts = sk_CMS_CertificateChoices_new_null();
+	if (!*pcerts)
+		return NULL;
+	cch = M_ASN1_new_of(CMS_CertificateChoices);
+	if (!cch)
+		return NULL;
+	if (!sk_CMS_CertificateChoices_push(*pcerts, cch))
+		{
+		M_ASN1_free_of(cch, CMS_CertificateChoices);
+		return NULL;
+		}
+	return cch;
+	}
+
+int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert)
+	{
+	CMS_CertificateChoices *cch;
+	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++)
+		{
+		cch = sk_CMS_CertificateChoices_value(*pcerts, i);
+		if (cch->type == CMS_CERTCHOICE_CERT)
+			{
+			if (!X509_cmp(cch->d.certificate, cert))
+				{
+				CMSerr(CMS_F_CMS_ADD0_CERT, 
+					CMS_R_CERTIFICATE_ALREADY_PRESENT);
+				return 0;
+				}
+			}
+		}
+	cch = CMS_add0_CertificateChoices(cms);
+	if (!cch)
+		return 0;
+	cch->type = CMS_CERTCHOICE_CERT;
+	cch->d.certificate = cert;
+	return 1;
+	}
+
+int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert)
+	{
+	int r;
+	r = CMS_add0_cert(cms, cert);
+	if (r > 0)
+		CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
+	return r;
+	}
+
+static STACK_OF(CMS_RevocationInfoChoice) **cms_get0_revocation_choices(CMS_ContentInfo *cms)
+	{
+	switch (OBJ_obj2nid(cms->contentType))
+		{
+
+		case NID_pkcs7_signed:
+		return &cms->d.signedData->crls;
+
+		case NID_pkcs7_enveloped:
+		return &cms->d.envelopedData->originatorInfo->crls;
+
+		default:
+		CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES,
+					CMS_R_UNSUPPORTED_CONTENT_TYPE);
+		return NULL;
+
+		}
+	}
+
+CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms)
+	{
+	STACK_OF(CMS_RevocationInfoChoice) **pcrls;
+	CMS_RevocationInfoChoice *rch;
+	pcrls = cms_get0_revocation_choices(cms);
+	if (!pcrls)
+		return NULL;
+	if (!*pcrls)
+		*pcrls = sk_CMS_RevocationInfoChoice_new_null();
+	if (!*pcrls)
+		return NULL;
+	rch = M_ASN1_new_of(CMS_RevocationInfoChoice);
+	if (!rch)
+		return NULL;
+	if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch))
+		{
+		M_ASN1_free_of(rch, CMS_RevocationInfoChoice);
+		return NULL;
+		}
+	return rch;
+	}
+
+int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl)
+	{
+	CMS_RevocationInfoChoice *rch;
+	rch = CMS_add0_RevocationInfoChoice(cms);
+	if (!rch)
+		return 0;
+	rch->type = CMS_REVCHOICE_CRL;
+	rch->d.crl = crl;
+	return 1;
+	}
+
+int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl)
+	{
+	int r;
+	r = CMS_add0_crl(cms, crl);
+	if (r > 0)
+		CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
+	return r;
+	}
+
+STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms)
+	{
+	STACK_OF(X509) *certs = NULL;
+	CMS_CertificateChoices *cch;
+	STACK_OF(CMS_CertificateChoices) **pcerts;
+	int i;
+	pcerts = cms_get0_certificate_choices(cms);
+	if (!pcerts)
+		return NULL;
+	for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++)
+		{
+		cch = sk_CMS_CertificateChoices_value(*pcerts, i);
+		if (cch->type == 0)
+			{
+			if (!certs)
+				{
+				certs = sk_X509_new_null();
+				if (!certs)
+					return NULL;
+				}
+			if (!sk_X509_push(certs, cch->d.certificate))
+				{
+				sk_X509_pop_free(certs, X509_free);
+				return NULL;
+				}
+			CRYPTO_add(&cch->d.certificate->references,
+						1, CRYPTO_LOCK_X509);
+			}
+		}
+	return certs;
+
+	}
+
+STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms)
+	{
+	STACK_OF(X509_CRL) *crls = NULL;
+	STACK_OF(CMS_RevocationInfoChoice) **pcrls;
+	CMS_RevocationInfoChoice *rch;
+	int i;
+	pcrls = cms_get0_revocation_choices(cms);
+	if (!pcrls)
+		return NULL;
+	for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++)
+		{
+		rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i);
+		if (rch->type == 0)
+			{
+			if (!crls)
+				{
+				crls = sk_X509_CRL_new_null();
+				if (!crls)
+					return NULL;
+				}
+			if (!sk_X509_CRL_push(crls, rch->d.crl))
+				{
+				sk_X509_CRL_pop_free(crls, X509_CRL_free);
+				return NULL;
+				}
+			CRYPTO_add(&rch->d.crl->references,
+						1, CRYPTO_LOCK_X509_CRL);
+			}
+		}
+	return crls;
+	}
diff --git a/crypto/cms/cms_pwri.c b/crypto/cms/cms_pwri.c
new file mode 100644
index 0000000..b79612a
--- /dev/null
+++ b/crypto/cms/cms_pwri.c
@@ -0,0 +1,454 @@
+/* crypto/cms/cms_pwri.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2009 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include <openssl/rand.h>
+#include <openssl/aes.h>
+#include "cms_lcl.h"
+#include "asn1_locl.h"
+
+int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, 
+				unsigned char *pass, ossl_ssize_t passlen)
+	{
+	CMS_PasswordRecipientInfo *pwri;
+	if (ri->type != CMS_RECIPINFO_PASS)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI);
+		return 0;
+		}
+
+	pwri = ri->d.pwri;
+	pwri->pass = pass;
+	if (pass && passlen < 0)
+		passlen = strlen((char *)pass);
+	pwri->passlen = passlen;
+	return 1;
+	}
+
+CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
+					int iter, int wrap_nid, int pbe_nid,
+					unsigned char *pass,
+					ossl_ssize_t passlen,
+					const EVP_CIPHER *kekciph)
+	{
+	CMS_RecipientInfo *ri = NULL;
+	CMS_EnvelopedData *env;
+	CMS_PasswordRecipientInfo *pwri;
+	EVP_CIPHER_CTX ctx;
+	X509_ALGOR *encalg = NULL;
+	unsigned char iv[EVP_MAX_IV_LENGTH];
+	int ivlen;
+	env = cms_get0_enveloped(cms);
+	if (!env)
+		goto err;
+
+	if (wrap_nid <= 0)
+		wrap_nid = NID_id_alg_PWRI_KEK;
+
+	if (pbe_nid <= 0)
+		pbe_nid = NID_id_pbkdf2;
+
+	/* Get from enveloped data */
+	if (kekciph == NULL)
+		kekciph = env->encryptedContentInfo->cipher;
+
+	if (kekciph == NULL)
+		{
+		CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER);
+		return NULL;
+		}
+	if (wrap_nid != NID_id_alg_PWRI_KEK)
+		{
+		CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
+				CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
+		return NULL;
+		}
+
+	/* Setup algorithm identifier for cipher */
+	encalg = X509_ALGOR_new();
+	EVP_CIPHER_CTX_init(&ctx);
+
+	if (EVP_EncryptInit_ex(&ctx, kekciph, NULL, NULL, NULL) <= 0)
+		{
+		CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB);
+		goto err;
+		}
+
+	ivlen = EVP_CIPHER_CTX_iv_length(&ctx);
+
+	if (ivlen > 0)
+		{
+		if (RAND_pseudo_bytes(iv, ivlen) <= 0)
+			goto err;
+		if (EVP_EncryptInit_ex(&ctx, NULL, NULL, NULL, iv) <= 0)
+			{
+			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
+							ERR_R_EVP_LIB);
+			goto err;
+			}
+		encalg->parameter = ASN1_TYPE_new();
+		if (!encalg->parameter)
+			{
+			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
+							ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		if (EVP_CIPHER_param_to_asn1(&ctx, encalg->parameter) <= 0)
+			{
+			CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
+				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
+			goto err;
+			}
+		}
+
+
+	encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(&ctx));
+
+	EVP_CIPHER_CTX_cleanup(&ctx);
+
+	/* Initialize recipient info */
+	ri = M_ASN1_new_of(CMS_RecipientInfo);
+	if (!ri)
+		goto merr;
+
+	ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo);
+	if (!ri->d.pwri)
+		goto merr;
+	ri->type = CMS_RECIPINFO_PASS;
+
+	pwri = ri->d.pwri;
+	/* Since this is overwritten, free up empty structure already there */
+	X509_ALGOR_free(pwri->keyEncryptionAlgorithm);
+	pwri->keyEncryptionAlgorithm = X509_ALGOR_new();
+	if (!pwri->keyEncryptionAlgorithm)
+		goto merr;
+	pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid);
+	pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new();
+	if (!pwri->keyEncryptionAlgorithm->parameter)
+		goto merr;
+
+        if(!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR),
+	    &pwri->keyEncryptionAlgorithm->parameter->value.sequence))
+		goto merr;
+        pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE;
+
+	X509_ALGOR_free(encalg);
+	encalg = NULL;
+
+	/* Setup PBE algorithm */
+
+	pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1);
+
+	if (!pwri->keyDerivationAlgorithm)
+		goto err;
+
+	CMS_RecipientInfo_set0_password(ri, pass, passlen);
+	pwri->version = 0;
+
+	if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
+		goto merr;
+
+	return ri;
+
+	merr:
+	CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE);
+	err:
+	EVP_CIPHER_CTX_cleanup(&ctx);
+	if (ri)
+		M_ASN1_free_of(ri, CMS_RecipientInfo);
+	if (encalg)
+		X509_ALGOR_free(encalg);
+	return NULL;
+
+	}
+
+/* This is an implementation of the key wrapping mechanism in RFC3211,
+ * at some point this should go into EVP.
+ */
+
+static int kek_unwrap_key(unsigned char *out, size_t *outlen,
+		const unsigned char *in, size_t inlen, EVP_CIPHER_CTX *ctx)
+	{
+	size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
+	unsigned char *tmp;
+	int outl, rv = 0;
+	if (inlen < 2 * blocklen)
+		{
+		/* too small */
+		return 0;
+		}
+	if (inlen % blocklen)
+		{
+		/* Invalid size */
+		return 0;
+		}
+	tmp = OPENSSL_malloc(inlen);
+	/* setup IV by decrypting last two blocks */
+	EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl,
+				in  + inlen - 2 * blocklen, blocklen * 2);
+	/* Do a decrypt of last decrypted block to set IV to correct value
+	 * output it to start of buffer so we don't corrupt decrypted block
+	 * this works because buffer is at least two block lengths long.
+	 */
+	EVP_DecryptUpdate(ctx, tmp, &outl,
+				tmp  + inlen - blocklen, blocklen);
+	/* Can now decrypt first n - 1 blocks */
+	EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen);
+
+	/* Reset IV to original value */
+	EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL);
+	/* Decrypt again */
+	EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen);
+	/* Check check bytes */
+	if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff)
+		{
+		/* Check byte failure */
+		goto err;
+		}
+	if (inlen < (size_t)(tmp[0] - 4 ))
+		{
+		/* Invalid length value */
+		goto err;
+		}
+	*outlen = (size_t)tmp[0];
+	memcpy(out, tmp + 4, *outlen);
+	rv = 1;
+	err:
+	OPENSSL_cleanse(tmp, inlen);
+	OPENSSL_free(tmp);
+	return rv;
+
+	}
+
+static int kek_wrap_key(unsigned char *out, size_t *outlen,
+		const unsigned char *in, size_t inlen, EVP_CIPHER_CTX *ctx)
+	{
+	size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
+	size_t olen;
+	int dummy;
+	/* First decide length of output buffer: need header and round up to
+	 * multiple of block length.
+	 */
+	olen = (inlen + 4 + blocklen - 1)/blocklen;
+	olen *= blocklen;
+	if (olen < 2 * blocklen)
+		{
+		/* Key too small */
+		return 0;
+		}
+	if (inlen > 0xFF)
+		{
+		/* Key too large */
+		return 0;
+		}
+	if (out)
+		{
+		/* Set header */
+		out[0] = (unsigned char)inlen;
+		out[1] = in[0] ^ 0xFF;
+		out[2] = in[1] ^ 0xFF;
+		out[3] = in[2] ^ 0xFF;
+		memcpy(out + 4, in, inlen);
+		/* Add random padding to end */
+		if (olen > inlen + 4)
+			RAND_pseudo_bytes(out + 4 + inlen, olen - 4 - inlen);
+		/* Encrypt twice */
+		EVP_EncryptUpdate(ctx, out, &dummy, out, olen);
+		EVP_EncryptUpdate(ctx, out, &dummy, out, olen);
+		}
+
+	*outlen = olen;
+
+	return 1;
+	}
+
+/* Encrypt/Decrypt content key in PWRI recipient info */
+
+int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
+							int en_de)
+	{
+	CMS_EncryptedContentInfo *ec;
+	CMS_PasswordRecipientInfo *pwri;
+	const unsigned char *p = NULL;
+	int plen;
+	int r = 0;
+	X509_ALGOR *algtmp, *kekalg = NULL;
+	EVP_CIPHER_CTX kekctx;
+	const EVP_CIPHER *kekcipher;
+	unsigned char *key = NULL;
+	size_t keylen;
+
+	ec = cms->d.envelopedData->encryptedContentInfo;
+
+	pwri = ri->d.pwri;
+	EVP_CIPHER_CTX_init(&kekctx);
+
+	if (!pwri->pass)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD);
+		return 0;
+		}
+	algtmp = pwri->keyEncryptionAlgorithm;
+
+	if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
+				CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
+		return 0;
+		}
+
+	if (algtmp->parameter->type == V_ASN1_SEQUENCE)
+		{
+		p = algtmp->parameter->value.sequence->data;
+		plen = algtmp->parameter->value.sequence->length;
+		kekalg = d2i_X509_ALGOR(NULL, &p, plen);
+		}
+	if (kekalg == NULL)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
+				CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER);
+		return 0;
+		}
+
+	kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
+		
+	if(!kekcipher)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
+				CMS_R_UNKNOWN_CIPHER);
+		goto err;
+		}
+
+	/* Fixup cipher based on AlgorithmIdentifier to set IV etc */
+	if (!EVP_CipherInit_ex(&kekctx, kekcipher, NULL, NULL, NULL, en_de))
+		goto err;
+	EVP_CIPHER_CTX_set_padding(&kekctx, 0);
+	if(EVP_CIPHER_asn1_to_param(&kekctx, kekalg->parameter) < 0)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
+				CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
+		goto err;
+		}
+
+	algtmp = pwri->keyDerivationAlgorithm;
+
+	/* Finish password based key derivation to setup key in "ctx" */
+
+	if (EVP_PBE_CipherInit(algtmp->algorithm,
+				(char *)pwri->pass, pwri->passlen,
+				algtmp->parameter, &kekctx, en_de) < 0)
+		{
+		CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB);
+		goto err;
+		}
+
+	/* Finally wrap/unwrap the key */
+
+	if (en_de)
+		{
+
+		if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, &kekctx))
+			goto err;
+
+		key = OPENSSL_malloc(keylen);
+
+		if (!key)
+			goto err;
+
+		if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, &kekctx))
+			goto err;
+		pwri->encryptedKey->data = key;
+		pwri->encryptedKey->length = keylen;
+		}
+	else
+		{
+		key = OPENSSL_malloc(pwri->encryptedKey->length);
+
+		if (!key)
+			{
+			CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
+							ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		if (!kek_unwrap_key(key, &keylen,
+					pwri->encryptedKey->data,
+					pwri->encryptedKey->length, &kekctx))
+			{
+			CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
+							CMS_R_UNWRAP_FAILURE);
+			goto err;
+			}
+
+		ec->key = key;
+		ec->keylen = keylen;
+
+		}
+
+	r = 1;
+
+	err:
+
+	EVP_CIPHER_CTX_cleanup(&kekctx);
+
+	if (!r && key)
+		OPENSSL_free(key);
+	X509_ALGOR_free(kekalg);
+
+	return r;
+
+	}
diff --git a/crypto/cms/cms_sd.c b/crypto/cms/cms_sd.c
new file mode 100644
index 0000000..77fbd13
--- /dev/null
+++ b/crypto/cms/cms_sd.c
@@ -0,0 +1,985 @@
+/* crypto/cms/cms_sd.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include "cms_lcl.h"
+#include "asn1_locl.h"
+
+/* CMS SignedData Utilities */
+
+DECLARE_ASN1_ITEM(CMS_SignedData)
+
+static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms)
+	{
+	if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed)
+		{
+		CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA);
+		return NULL;
+		}
+	return cms->d.signedData;
+	}
+
+static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms)
+	{
+	if (cms->d.other == NULL)
+		{
+		cms->d.signedData = M_ASN1_new_of(CMS_SignedData);
+		if (!cms->d.signedData)
+			{
+			CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE);
+			return NULL;
+			}
+		cms->d.signedData->version = 1;
+		cms->d.signedData->encapContentInfo->eContentType =
+						OBJ_nid2obj(NID_pkcs7_data);
+		cms->d.signedData->encapContentInfo->partial = 1;
+		ASN1_OBJECT_free(cms->contentType);
+		cms->contentType = OBJ_nid2obj(NID_pkcs7_signed);
+		return cms->d.signedData;
+		}
+	return cms_get0_signed(cms);
+	}
+
+/* Just initialize SignedData e.g. for certs only structure */
+
+int CMS_SignedData_init(CMS_ContentInfo *cms)
+	{
+	if (cms_signed_data_init(cms))
+		return 1;
+	else
+		return 0;
+	}
+
+/* Check structures and fixup version numbers (if necessary) */
+
+static void cms_sd_set_version(CMS_SignedData *sd)
+	{
+	int i;
+	CMS_CertificateChoices *cch;
+	CMS_RevocationInfoChoice *rch;
+	CMS_SignerInfo *si;
+
+	for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++)
+		{
+		cch = sk_CMS_CertificateChoices_value(sd->certificates, i);
+		if (cch->type == CMS_CERTCHOICE_OTHER)
+			{
+			if (sd->version < 5)
+				sd->version = 5;
+			}
+		else if (cch->type == CMS_CERTCHOICE_V2ACERT)
+			{
+			if (sd->version < 4)
+				sd->version = 4;
+			}
+		else if (cch->type == CMS_CERTCHOICE_V1ACERT)
+			{
+			if (sd->version < 3)
+				sd->version = 3;
+			}
+		}
+
+	for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++)
+		{
+		rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i);
+		if (rch->type == CMS_REVCHOICE_OTHER)
+			{
+			if (sd->version < 5)
+				sd->version = 5;
+			}
+		}
+
+	if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data)
+			&& (sd->version < 3))
+		sd->version = 3;
+
+	for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++)
+		{
+		si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
+		if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
+			{
+			if (si->version < 3)
+				si->version = 3;
+			if (sd->version < 3)
+				sd->version = 3;
+			}
+		else
+			sd->version = 1;
+		}
+
+	if (sd->version < 1)
+		sd->version = 1;
+
+	}
+	
+/* Copy an existing messageDigest value */
+
+static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
+	{
+	STACK_OF(CMS_SignerInfo) *sinfos;
+	CMS_SignerInfo *sitmp;
+	int i;
+	sinfos = CMS_get0_SignerInfos(cms);
+	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
+		{
+		ASN1_OCTET_STRING *messageDigest;
+		sitmp = sk_CMS_SignerInfo_value(sinfos, i);
+		if (sitmp == si)
+			continue;
+		if (CMS_signed_get_attr_count(sitmp) < 0)
+			continue;
+		if (OBJ_cmp(si->digestAlgorithm->algorithm,
+				sitmp->digestAlgorithm->algorithm))
+			continue;
+		messageDigest = CMS_signed_get0_data_by_OBJ(sitmp,
+					OBJ_nid2obj(NID_pkcs9_messageDigest),
+					-3, V_ASN1_OCTET_STRING);
+		if (!messageDigest)
+			{
+			CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST,
+				CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
+			return 0;
+			}
+
+		if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
+						V_ASN1_OCTET_STRING,
+						messageDigest, -1))
+			return 1;
+		else
+			return 0;
+		}
+		CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST);
+		return 0;
+	}
+
+int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type)
+	{
+	switch(type)
+		{
+		case CMS_SIGNERINFO_ISSUER_SERIAL:
+		sid->d.issuerAndSerialNumber =
+			M_ASN1_new_of(CMS_IssuerAndSerialNumber);
+		if (!sid->d.issuerAndSerialNumber)
+			goto merr;
+		if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer,
+					X509_get_issuer_name(cert)))
+			goto merr;
+		if (!ASN1_STRING_copy(
+			sid->d.issuerAndSerialNumber->serialNumber,
+				X509_get_serialNumber(cert)))
+			goto merr;
+		break;
+
+		case CMS_SIGNERINFO_KEYIDENTIFIER:
+		if (!cert->skid)
+			{
+			CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER,
+					CMS_R_CERTIFICATE_HAS_NO_KEYID);
+			return 0;
+			}
+		sid->d.subjectKeyIdentifier = ASN1_STRING_dup(cert->skid);
+		if (!sid->d.subjectKeyIdentifier)
+			goto merr;
+		break;
+
+		default:
+		CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID);
+		return 0;
+		}
+
+	sid->type = type;
+
+	return 1;
+
+	merr:
+	CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, ERR_R_MALLOC_FAILURE);
+	return 0;
+
+	}
+
+int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
+					ASN1_OCTET_STRING **keyid,
+					X509_NAME **issuer, ASN1_INTEGER **sno)
+	{
+	if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
+		{
+		if (issuer)
+			*issuer = sid->d.issuerAndSerialNumber->issuer;
+		if (sno)
+			*sno = sid->d.issuerAndSerialNumber->serialNumber;
+		}
+	else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
+		{
+		if (keyid)
+			*keyid = sid->d.subjectKeyIdentifier;
+		}
+	else
+		return 0;
+	return 1;
+	}
+
+int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
+	{
+	int ret;
+	if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
+		{
+		ret = X509_NAME_cmp(sid->d.issuerAndSerialNumber->issuer,
+					X509_get_issuer_name(cert));
+		if (ret)
+			return ret;
+		return ASN1_INTEGER_cmp(sid->d.issuerAndSerialNumber->serialNumber,
+					X509_get_serialNumber(cert));
+		}
+	else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
+		{
+		X509_check_purpose(cert, -1, -1);
+		if (!cert->skid)
+			return -1;
+		return ASN1_OCTET_STRING_cmp(sid->d.subjectKeyIdentifier,
+							cert->skid);
+		}
+	else
+		return -1;
+	}
+
+CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
+			X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
+			unsigned int flags)
+	{
+	CMS_SignedData *sd;
+	CMS_SignerInfo *si = NULL;
+	X509_ALGOR *alg;
+	int i, type;
+	if(!X509_check_private_key(signer, pk))
+		{
+		CMSerr(CMS_F_CMS_ADD1_SIGNER,
+			CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+                return NULL;
+		}
+	sd = cms_signed_data_init(cms);
+	if (!sd)
+		goto err;
+	si = M_ASN1_new_of(CMS_SignerInfo);
+	if (!si)
+		goto merr;
+	X509_check_purpose(signer, -1, -1);
+
+	CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY);
+	CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
+
+	si->pkey = pk;
+	si->signer = signer;
+
+	if (flags & CMS_USE_KEYID)
+		{
+		si->version = 3;
+		if (sd->version < 3)
+			sd->version = 3;
+		type = CMS_SIGNERINFO_KEYIDENTIFIER;
+		}
+	else
+		{
+		type = CMS_SIGNERINFO_ISSUER_SERIAL;
+		si->version = 1;
+		}
+
+	if (!cms_set1_SignerIdentifier(si->sid, signer, type))
+		goto err;
+
+	if (md == NULL)
+		{
+		int def_nid;
+		if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0)
+			goto err;
+		md = EVP_get_digestbynid(def_nid);
+		if (md == NULL)
+			{
+			CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST);
+			goto err;
+			}
+		}
+
+	if (!md)
+		{
+		CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET);
+		goto err;
+		}
+
+	cms_DigestAlgorithm_set(si->digestAlgorithm, md);
+
+	/* See if digest is present in digestAlgorithms */
+	for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++)
+		{
+		ASN1_OBJECT *aoid;
+		alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
+		X509_ALGOR_get0(&aoid, NULL, NULL, alg);
+		if (OBJ_obj2nid(aoid) == EVP_MD_type(md))
+			break;
+		}
+
+	if (i == sk_X509_ALGOR_num(sd->digestAlgorithms))
+		{
+		alg = X509_ALGOR_new();
+		if (!alg)
+			goto merr;
+		cms_DigestAlgorithm_set(alg, md);
+		if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg))
+			{
+			X509_ALGOR_free(alg);
+			goto merr;
+			}
+		}
+
+	if (pk->ameth && pk->ameth->pkey_ctrl)
+		{
+		i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_SIGN,
+						0, si);
+		if (i == -2)
+			{
+			CMSerr(CMS_F_CMS_ADD1_SIGNER,
+				CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+			goto err;
+			}
+		if (i <= 0)
+			{
+			CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_CTRL_FAILURE);
+			goto err;
+			}
+		}
+
+	if (!(flags & CMS_NOATTR))
+		{
+		/* Initialialize signed attributes strutucture so other
+		 * attributes such as signing time etc are added later
+		 * even if we add none here.
+		 */
+		if (!si->signedAttrs)
+			{
+			si->signedAttrs = sk_X509_ATTRIBUTE_new_null();
+			if (!si->signedAttrs)
+				goto merr;
+			}
+
+		if (!(flags & CMS_NOSMIMECAP))
+			{
+			STACK_OF(X509_ALGOR) *smcap = NULL;
+			i = CMS_add_standard_smimecap(&smcap);
+			if (i)
+				i = CMS_add_smimecap(si, smcap);
+			sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
+			if (!i)
+				goto merr;
+			}
+		if (flags & CMS_REUSE_DIGEST)
+			{
+			if (!cms_copy_messageDigest(cms, si))
+				goto err;
+			if (!(flags & CMS_PARTIAL) &&
+					!CMS_SignerInfo_sign(si))
+				goto err;
+			}
+		}
+
+	if (!(flags & CMS_NOCERTS))
+		{
+		/* NB ignore -1 return for duplicate cert */
+		if (!CMS_add1_cert(cms, signer))
+			goto merr;
+		}
+
+	if (!sd->signerInfos)
+		sd->signerInfos = sk_CMS_SignerInfo_new_null();
+	if (!sd->signerInfos ||
+		!sk_CMS_SignerInfo_push(sd->signerInfos, si))
+		goto merr;
+
+	return si;
+
+	merr:
+	CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);
+	err:
+	if (si)
+		M_ASN1_free_of(si, CMS_SignerInfo);
+	return NULL;
+
+	}
+
+static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
+	{
+	ASN1_TIME *tt;
+	int r = 0;
+	if (t)
+		tt = t;
+	else
+		tt = X509_gmtime_adj(NULL, 0);
+
+	if (!tt)
+		goto merr;
+
+	if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime,
+						tt->type, tt, -1) <= 0)
+		goto merr;
+
+	r = 1;
+
+	merr:
+
+	if (!t)
+		ASN1_TIME_free(tt);
+
+	if (!r)
+		CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE);
+
+	return r;
+
+	}
+
+STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)
+	{
+	CMS_SignedData *sd;
+	sd = cms_get0_signed(cms);
+	if (!sd)
+		return NULL;
+	return sd->signerInfos;
+	}
+
+STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
+	{
+	STACK_OF(X509) *signers = NULL;
+	STACK_OF(CMS_SignerInfo) *sinfos;
+	CMS_SignerInfo *si;
+	int i;
+	sinfos = CMS_get0_SignerInfos(cms);
+	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
+		{
+		si = sk_CMS_SignerInfo_value(sinfos, i);
+		if (si->signer)
+			{
+			if (!signers)
+				{
+				signers = sk_X509_new_null();
+				if (!signers)
+					return NULL;
+				}
+			if (!sk_X509_push(signers, si->signer))
+				{
+				sk_X509_free(signers);
+				return NULL;
+				}
+			}
+		}
+	return signers;
+	}
+
+void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer)
+	{
+	if (signer)
+		{
+		CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
+		if (si->pkey)
+			EVP_PKEY_free(si->pkey);
+		si->pkey = X509_get_pubkey(signer);
+		}
+	if (si->signer)
+		X509_free(si->signer);
+	si->signer = signer;
+	}
+
+int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
+					ASN1_OCTET_STRING **keyid,
+					X509_NAME **issuer, ASN1_INTEGER **sno)
+	{
+	return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno);
+	}
+
+int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert)
+	{
+	return cms_SignerIdentifier_cert_cmp(si->sid, cert);
+	}
+
+int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
+				unsigned int flags)
+	{
+	CMS_SignedData *sd;
+	CMS_SignerInfo *si;
+	CMS_CertificateChoices *cch;
+	STACK_OF(CMS_CertificateChoices) *certs;
+	X509 *x;
+	int i, j;
+	int ret = 0;
+	sd = cms_get0_signed(cms);
+	if (!sd)
+		return -1;
+	certs = sd->certificates;
+	for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++)
+		{
+		si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
+		if (si->signer)
+			continue;
+
+		for (j = 0; j < sk_X509_num(scerts); j++)
+			{
+			x = sk_X509_value(scerts, j);
+			if (CMS_SignerInfo_cert_cmp(si, x) == 0)
+				{
+				CMS_SignerInfo_set1_signer_cert(si, x);
+				ret++;
+				break;
+				}
+			}
+
+		if (si->signer || (flags & CMS_NOINTERN))
+			continue;
+
+		for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++)
+			{
+			cch = sk_CMS_CertificateChoices_value(certs, j);
+			if (cch->type != 0)
+				continue;
+			x = cch->d.certificate;
+			if (CMS_SignerInfo_cert_cmp(si, x) == 0)
+				{
+				CMS_SignerInfo_set1_signer_cert(si, x);
+				ret++;
+				break;
+				}
+			}
+		}
+	return ret;
+	}
+
+void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer,
+					X509_ALGOR **pdig, X509_ALGOR **psig)
+	{
+	if (pk)
+		*pk = si->pkey;
+	if (signer)
+		*signer = si->signer;
+	if (pdig)
+		*pdig = si->digestAlgorithm;
+	if (psig)
+		*psig = si->signatureAlgorithm;
+	}
+
+static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
+					CMS_SignerInfo *si, BIO *chain)
+	{
+	EVP_MD_CTX mctx;
+	int r = 0;
+	EVP_MD_CTX_init(&mctx);
+
+
+	if (!si->pkey)
+		{
+		CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY);
+		return 0;
+		}
+
+	if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
+		goto err;
+
+	/* If any signed attributes calculate and add messageDigest attribute */
+
+	if (CMS_signed_get_attr_count(si) >= 0)
+		{
+		ASN1_OBJECT *ctype =
+			cms->d.signedData->encapContentInfo->eContentType; 
+		unsigned char md[EVP_MAX_MD_SIZE];
+		unsigned int mdlen;
+		if (!EVP_DigestFinal_ex(&mctx, md, &mdlen))
+			goto err;
+		if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
+						V_ASN1_OCTET_STRING,
+						md, mdlen))
+			goto err;
+		/* Copy content type across */
+		if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
+					V_ASN1_OBJECT, ctype, -1) <= 0)
+			goto err;
+		if (!CMS_SignerInfo_sign(si))
+			goto err;
+		}
+	else
+		{
+		unsigned char *sig;
+		unsigned int siglen;
+		sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey));
+		if (!sig)
+			{
+			CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN,
+					ERR_R_MALLOC_FAILURE);
+			goto err;
+			}
+		if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey))
+			{
+			CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN,
+					CMS_R_SIGNFINAL_ERROR);
+			OPENSSL_free(sig);
+			goto err;
+			}
+		ASN1_STRING_set0(si->signature, sig, siglen);
+		}
+
+	r = 1;
+
+	err:
+	EVP_MD_CTX_cleanup(&mctx);
+	return r;
+
+	}
+
+int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
+	{
+	STACK_OF(CMS_SignerInfo) *sinfos;
+	CMS_SignerInfo *si;
+	int i;
+	sinfos = CMS_get0_SignerInfos(cms);
+	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
+		{
+		si = sk_CMS_SignerInfo_value(sinfos, i);
+		if (!cms_SignerInfo_content_sign(cms, si, chain))
+			return 0;
+		}
+	cms->d.signedData->encapContentInfo->partial = 0;
+	return 1;
+	}
+
+int CMS_SignerInfo_sign(CMS_SignerInfo *si)
+	{
+	EVP_MD_CTX mctx;
+	EVP_PKEY_CTX *pctx;
+	unsigned char *abuf = NULL;
+	int alen;
+	size_t siglen;
+	const EVP_MD *md = NULL;
+
+	md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
+	if (md == NULL)
+		return 0;
+
+	EVP_MD_CTX_init(&mctx);
+
+	if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0)
+		{
+		if (!cms_add1_signingTime(si, NULL))
+			goto err;
+		}
+
+	if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
+				EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0)
+		{
+		CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
+		goto err;
+		}
+
+	alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf,
+				ASN1_ITEM_rptr(CMS_Attributes_Sign));
+	if(!abuf)
+		goto err;
+	if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0)
+		goto err;
+	if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
+		goto err;
+	OPENSSL_free(abuf);
+	abuf = OPENSSL_malloc(siglen);
+	if(!abuf)
+		goto err;
+	if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
+		goto err;
+
+	if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
+				EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0)
+		{
+		CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
+		goto err;
+		}
+
+	EVP_MD_CTX_cleanup(&mctx);
+
+	ASN1_STRING_set0(si->signature, abuf, siglen);
+
+	return 1;
+
+	err:
+	if (abuf)
+		OPENSSL_free(abuf);
+	EVP_MD_CTX_cleanup(&mctx);
+	return 0;
+
+	}
+
+int CMS_SignerInfo_verify(CMS_SignerInfo *si)
+	{
+	EVP_MD_CTX mctx;
+	EVP_PKEY_CTX *pctx;
+	unsigned char *abuf = NULL;
+	int alen, r = -1;
+	const EVP_MD *md = NULL;
+
+	if (!si->pkey)
+		{
+		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY);
+		return -1;
+		}
+
+	md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
+	if (md == NULL)
+		return -1;
+	EVP_MD_CTX_init(&mctx);
+	if (EVP_DigestVerifyInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
+		goto err;
+
+	alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs,&abuf,
+				ASN1_ITEM_rptr(CMS_Attributes_Verify));
+	if(!abuf)
+		goto err;
+	r = EVP_DigestVerifyUpdate(&mctx, abuf, alen);
+	OPENSSL_free(abuf);
+	if (r <= 0)
+		{
+		r = -1;
+		goto err;
+		}
+	r = EVP_DigestVerifyFinal(&mctx,
+			si->signature->data, si->signature->length);
+	if (r <= 0)
+		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE);
+	err:
+	EVP_MD_CTX_cleanup(&mctx);
+	return r;
+	}
+
+/* Create a chain of digest BIOs from a CMS ContentInfo */
+
+BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms)
+	{
+	int i;
+	CMS_SignedData *sd;
+	BIO *chain = NULL;
+	sd = cms_get0_signed(cms);
+	if (!sd)
+		return NULL;
+	if (cms->d.signedData->encapContentInfo->partial)
+		cms_sd_set_version(sd);
+	for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++)
+		{
+		X509_ALGOR *digestAlgorithm;
+		BIO *mdbio;
+		digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
+		mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm);
+		if (!mdbio)
+			goto err;	
+		if (chain)
+			 BIO_push(chain, mdbio);
+		else
+			chain = mdbio;
+		}
+	return chain;
+	err:
+	if (chain)
+		BIO_free_all(chain);
+	return NULL;
+	}
+
+int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
+	{
+	ASN1_OCTET_STRING *os = NULL;
+	EVP_MD_CTX mctx;
+	int r = -1;
+	EVP_MD_CTX_init(&mctx);
+	/* If we have any signed attributes look for messageDigest value */
+	if (CMS_signed_get_attr_count(si) >= 0)
+		{
+		os = CMS_signed_get0_data_by_OBJ(si,
+					OBJ_nid2obj(NID_pkcs9_messageDigest),
+					-3, V_ASN1_OCTET_STRING);
+		if (!os)
+			{
+			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+				CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
+			goto err;
+			}
+		}
+
+	if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
+		goto err;
+
+	/* If messageDigest found compare it */
+
+	if (os)
+		{
+		unsigned char mval[EVP_MAX_MD_SIZE];
+		unsigned int mlen;
+		if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0)
+			{
+			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+				CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
+			goto err;
+			}
+		if (mlen != (unsigned int)os->length)
+			{
+			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+				CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);
+			goto err;
+			}
+
+		if (memcmp(mval, os->data, mlen))
+			{
+			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+				CMS_R_VERIFICATION_FAILURE);
+			r = 0;
+			}
+		else
+			r = 1;
+		}
+	else
+		{
+		r = EVP_VerifyFinal(&mctx, si->signature->data,
+					si->signature->length, si->pkey);
+		if (r <= 0)
+			{
+			CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+				CMS_R_VERIFICATION_FAILURE);
+			r = 0;
+			}
+		}
+
+	err:
+	EVP_MD_CTX_cleanup(&mctx);
+	return r;
+
+	}
+
+int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs)
+	{
+	unsigned char *smder = NULL;
+	int smderlen, r;
+	smderlen = i2d_X509_ALGORS(algs, &smder);
+	if (smderlen <= 0)
+		return 0;
+	r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities,
+					V_ASN1_SEQUENCE, smder, smderlen);
+	OPENSSL_free(smder);
+	return r;
+	}
+
+int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
+				int algnid, int keysize)
+	{
+	X509_ALGOR *alg;
+	ASN1_INTEGER *key = NULL;
+	if (keysize > 0)
+		{
+		key = ASN1_INTEGER_new();
+		if (!key || !ASN1_INTEGER_set(key, keysize))
+			return 0;
+		}
+	alg = X509_ALGOR_new();
+	if (!alg)
+		{
+		if (key)
+			ASN1_INTEGER_free(key);
+		return 0;
+		}
+		
+	X509_ALGOR_set0(alg, OBJ_nid2obj(algnid),
+				key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key);
+	if (!*algs)
+		*algs = sk_X509_ALGOR_new_null();
+	if (!*algs || !sk_X509_ALGOR_push(*algs, alg))
+		{
+		X509_ALGOR_free(alg);
+		return 0;
+		}
+	return 1;
+	}
+
+/* Check to see if a cipher exists and if so add S/MIME capabilities */
+
+static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
+	{
+	if (EVP_get_cipherbynid(nid))
+		return CMS_add_simple_smimecap(sk, nid, arg);
+	return 1;
+	}
+
+static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
+	{
+	if (EVP_get_digestbynid(nid))
+		return CMS_add_simple_smimecap(sk, nid, arg);
+	return 1;
+	}
+
+int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap)
+	{
+	if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
+		|| !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
+		|| !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
+		|| !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
+		|| !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
+		|| !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
+		|| !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128)
+		|| !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64)
+		|| !cms_add_cipher_smcap(smcap, NID_des_cbc, -1)
+		|| !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40))
+		return 0;
+	return 1;
+	}
diff --git a/crypto/cms/cms_smime.c b/crypto/cms/cms_smime.c
new file mode 100644
index 0000000..8c56e3a
--- /dev/null
+++ b/crypto/cms/cms_smime.c
@@ -0,0 +1,850 @@
+/* crypto/cms/cms_smime.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include "cms_lcl.h"
+
+static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
+	{
+	unsigned char buf[4096];
+	int r = 0, i;
+	BIO *tmpout = NULL;
+
+	if (out == NULL)
+		tmpout = BIO_new(BIO_s_null());
+	else if (flags & CMS_TEXT)
+		{
+		tmpout = BIO_new(BIO_s_mem());
+		BIO_set_mem_eof_return(tmpout, 0);
+		}
+	else
+		tmpout = out;
+
+	if(!tmpout)
+		{
+		CMSerr(CMS_F_CMS_COPY_CONTENT,ERR_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	/* Read all content through chain to process digest, decrypt etc */
+	for (;;)
+	{
+		i=BIO_read(in,buf,sizeof(buf));
+		if (i <= 0)
+			{
+			if (BIO_method_type(in) == BIO_TYPE_CIPHER)
+				{
+				if (!BIO_get_cipher_status(in))
+					goto err;
+				}
+			if (i < 0)
+				goto err;
+			break;
+			}
+				
+		if (tmpout && (BIO_write(tmpout, buf, i) != i))
+			goto err;
+	}
+
+	if(flags & CMS_TEXT)
+		{
+		if(!SMIME_text(tmpout, out))
+			{
+			CMSerr(CMS_F_CMS_COPY_CONTENT,CMS_R_SMIME_TEXT_ERROR);
+			goto err;
+			}
+		}
+
+	r = 1;
+
+	err:
+	if (tmpout && (tmpout != out))
+		BIO_free(tmpout);
+	return r;
+
+	}
+
+static int check_content(CMS_ContentInfo *cms)
+	{
+	ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
+	if (!pos || !*pos)
+		{
+		CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT);
+		return 0;
+		}
+	return 1;
+	}
+
+static void do_free_upto(BIO *f, BIO *upto)
+	{
+	if (upto)
+		{
+		BIO *tbio;
+		do 
+			{
+			tbio = BIO_pop(f);
+			BIO_free(f);
+			f = tbio;
+			}
+		while (f != upto);
+		}
+	else
+		BIO_free_all(f);
+	}
+
+int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags)
+	{
+	BIO *cont;
+	int r;
+	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data)
+		{
+		CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA);
+		return 0;
+		}
+	cont = CMS_dataInit(cms, NULL);
+	if (!cont)
+		return 0;
+	r = cms_copy_content(out, cont, flags);
+	BIO_free_all(cont);
+	return r;
+	}
+
+CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags)
+	{
+	CMS_ContentInfo *cms;
+	cms = cms_Data_create();
+	if (!cms)
+		return NULL;
+
+	if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
+		return cms;
+
+	CMS_ContentInfo_free(cms);
+
+	return NULL;
+	}
+
+int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+							unsigned int flags)
+	{
+	BIO *cont;
+	int r;
+	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest)
+		{
+		CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA);
+		return 0;
+		}
+
+	if (!dcont && !check_content(cms))
+		return 0;
+
+	cont = CMS_dataInit(cms, dcont);
+	if (!cont)
+		return 0;
+	r = cms_copy_content(out, cont, flags);
+	if (r)
+		r = cms_DigestedData_do_final(cms, cont, 1);
+	do_free_upto(cont, dcont);
+	return r;
+	}
+
+CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
+					unsigned int flags)
+	{
+	CMS_ContentInfo *cms;
+	if (!md)
+		md = EVP_sha1();
+	cms = cms_DigestedData_create(md);
+	if (!cms)
+		return NULL;
+
+	if(!(flags & CMS_DETACHED))
+		CMS_set_detached(cms, 0);
+
+	if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
+		return cms;
+
+	CMS_ContentInfo_free(cms);
+	return NULL;
+	}
+
+int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
+				const unsigned char *key, size_t keylen,
+				BIO *dcont, BIO *out, unsigned int flags)
+	{
+	BIO *cont;
+	int r;
+	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted)
+		{
+		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT,
+					CMS_R_TYPE_NOT_ENCRYPTED_DATA);
+		return 0;
+		}
+
+	if (!dcont && !check_content(cms))
+		return 0;
+
+	if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0)
+		return 0;
+	cont = CMS_dataInit(cms, dcont);
+	if (!cont)
+		return 0;
+	r = cms_copy_content(out, cont, flags);
+	do_free_upto(cont, dcont);
+	return r;
+	}
+
+CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
+					const unsigned char *key, size_t keylen,
+					unsigned int flags)
+	{
+	CMS_ContentInfo *cms;
+	if (!cipher)
+		{
+		CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER);
+		return NULL;
+		}
+	cms = CMS_ContentInfo_new();
+	if (!cms)
+		return NULL;
+	if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen))
+		return NULL;
+
+	if(!(flags & CMS_DETACHED))
+		CMS_set_detached(cms, 0);
+
+	if ((flags & (CMS_STREAM|CMS_PARTIAL))
+		|| CMS_final(cms, in, NULL, flags))
+		return cms;
+
+	CMS_ContentInfo_free(cms);
+	return NULL;
+	}
+
+static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
+					X509_STORE *store,
+					STACK_OF(X509) *certs,
+					STACK_OF(X509_CRL) *crls,
+					unsigned int flags)
+	{
+	X509_STORE_CTX ctx;
+	X509 *signer;
+	int i, j, r = 0;
+	CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
+	if (!X509_STORE_CTX_init(&ctx, store, signer, certs))
+		{
+		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT,
+						CMS_R_STORE_INIT_ERROR);
+		goto err;
+		}
+	X509_STORE_CTX_set_default(&ctx, "smime_sign");
+	if (crls)
+		X509_STORE_CTX_set0_crls(&ctx, crls);
+
+	i = X509_verify_cert(&ctx);
+	if (i <= 0)
+		{
+		j = X509_STORE_CTX_get_error(&ctx);
+		CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT,
+						CMS_R_CERTIFICATE_VERIFY_ERROR);
+		ERR_add_error_data(2, "Verify error:",
+					 X509_verify_cert_error_string(j));
+		goto err;
+		}
+	r = 1;
+	err:
+	X509_STORE_CTX_cleanup(&ctx);
+	return r;
+
+	}
+
+int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
+		 X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags)
+	{
+	CMS_SignerInfo *si;
+	STACK_OF(CMS_SignerInfo) *sinfos;
+	STACK_OF(X509) *cms_certs = NULL;
+	STACK_OF(X509_CRL) *crls = NULL;
+	X509 *signer;
+	int i, scount = 0, ret = 0;
+	BIO *cmsbio = NULL, *tmpin = NULL;
+
+	if (!dcont && !check_content(cms))
+		return 0;
+
+	/* Attempt to find all signer certificates */
+
+	sinfos = CMS_get0_SignerInfos(cms);
+
+	if (sk_CMS_SignerInfo_num(sinfos) <= 0)
+		{
+		CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_SIGNERS);
+		goto err;
+		}
+
+	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
+		{
+		si = sk_CMS_SignerInfo_value(sinfos, i);
+		CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
+		if (signer)
+			scount++;
+		}
+
+	if (scount != sk_CMS_SignerInfo_num(sinfos))
+		scount += CMS_set1_signers_certs(cms, certs, flags);
+
+	if (scount != sk_CMS_SignerInfo_num(sinfos))
+		{
+		CMSerr(CMS_F_CMS_VERIFY, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND);
+		goto err;
+		}
+
+	/* Attempt to verify all signers certs */
+
+	if (!(flags & CMS_NO_SIGNER_CERT_VERIFY))
+		{
+		cms_certs = CMS_get1_certs(cms);
+		if (!(flags & CMS_NOCRL))
+			crls = CMS_get1_crls(cms);
+		for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
+			{
+			si = sk_CMS_SignerInfo_value(sinfos, i);
+			if (!cms_signerinfo_verify_cert(si, store,
+							cms_certs, crls, flags))
+				goto err;
+			}
+		}
+
+	/* Attempt to verify all SignerInfo signed attribute signatures */
+
+	if (!(flags & CMS_NO_ATTR_VERIFY))
+		{
+		for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
+			{
+			si = sk_CMS_SignerInfo_value(sinfos, i);
+			if (CMS_signed_get_attr_count(si) < 0)
+				continue;
+			if (CMS_SignerInfo_verify(si) <= 0)
+				goto err;
+			}
+		}
+
+	/* Performance optimization: if the content is a memory BIO then
+	 * store its contents in a temporary read only memory BIO. This
+	 * avoids potentially large numbers of slow copies of data which will
+	 * occur when reading from a read write memory BIO when signatures
+	 * are calculated.
+	 */
+
+	if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM))
+		{
+		char *ptr;
+		long len;
+		len = BIO_get_mem_data(dcont, &ptr);
+		tmpin = BIO_new_mem_buf(ptr, len);
+		if (tmpin == NULL)
+			{
+			CMSerr(CMS_F_CMS_VERIFY,ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		}
+	else
+		tmpin = dcont;
+		
+
+	cmsbio=CMS_dataInit(cms, tmpin);
+	if (!cmsbio)
+		goto err;
+
+	if (!cms_copy_content(out, cmsbio, flags))
+		goto err;
+
+	if (!(flags & CMS_NO_CONTENT_VERIFY))
+		{
+		for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
+			{
+			si = sk_CMS_SignerInfo_value(sinfos, i);
+			if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0)
+				{
+				CMSerr(CMS_F_CMS_VERIFY,
+					CMS_R_CONTENT_VERIFY_ERROR);
+				goto err;
+				}
+			}
+		}
+
+	ret = 1;
+
+	err:
+	
+	if (dcont && (tmpin == dcont))
+		do_free_upto(cmsbio, dcont);
+	else
+		BIO_free_all(cmsbio);
+
+	if (cms_certs)
+		sk_X509_pop_free(cms_certs, X509_free);
+	if (crls)
+		sk_X509_CRL_pop_free(crls, X509_CRL_free);
+
+	return ret;
+	}
+
+int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
+			STACK_OF(X509) *certs,
+			X509_STORE *store, unsigned int flags)
+	{
+	int r;
+	flags &= ~(CMS_DETACHED|CMS_TEXT);
+	r = CMS_verify(rcms, certs, store, NULL, NULL, flags);
+	if (r <= 0)
+		return r;
+	return cms_Receipt_verify(rcms, ocms);
+	}
+
+CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
+						BIO *data, unsigned int flags)
+	{
+	CMS_ContentInfo *cms;
+	int i;
+
+	cms = CMS_ContentInfo_new();
+	if (!cms || !CMS_SignedData_init(cms))
+		goto merr;
+
+	if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags))
+		{
+		CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR);
+		goto err;
+		}
+
+	for (i = 0; i < sk_X509_num(certs); i++)
+		{
+		X509 *x = sk_X509_value(certs, i);
+		if (!CMS_add1_cert(cms, x))
+			goto merr;
+		}
+
+	if(!(flags & CMS_DETACHED))
+		CMS_set_detached(cms, 0);
+
+	if ((flags & (CMS_STREAM|CMS_PARTIAL))
+		|| CMS_final(cms, data, NULL, flags))
+		return cms;
+	else
+		goto err;
+
+	merr:
+	CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE);
+
+	err:
+	if (cms)
+		CMS_ContentInfo_free(cms);
+	return NULL;
+	}
+
+CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
+					X509 *signcert, EVP_PKEY *pkey,
+					STACK_OF(X509) *certs,
+					unsigned int flags)
+	{
+	CMS_SignerInfo *rct_si;
+	CMS_ContentInfo *cms = NULL;
+	ASN1_OCTET_STRING **pos, *os;
+	BIO *rct_cont = NULL;
+	int r = 0;
+
+	flags &= ~(CMS_STREAM|CMS_TEXT);
+	/* Not really detached but avoids content being allocated */
+	flags |= CMS_PARTIAL|CMS_BINARY|CMS_DETACHED;
+	if (!pkey || !signcert)
+		{
+		CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT);
+		return NULL;
+		}
+
+	/* Initialize signed data */
+
+	cms = CMS_sign(NULL, NULL, certs, NULL, flags);
+	if (!cms)
+		goto err;
+
+	/* Set inner content type to signed receipt */
+	if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt)))
+		goto err;
+
+	rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags);
+	if (!rct_si)
+		{
+		CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR);
+		goto err;
+		}
+
+	os = cms_encode_Receipt(si);
+
+	if (!os)
+		goto err;
+
+	/* Set content to digest */
+	rct_cont = BIO_new_mem_buf(os->data, os->length);
+	if (!rct_cont)
+		goto err;
+
+	/* Add msgSigDigest attribute */
+
+	if (!cms_msgSigDigest_add1(rct_si, si))
+		goto err;
+
+	/* Finalize structure */
+	if (!CMS_final(cms, rct_cont, NULL, flags))
+		goto err;
+
+	/* Set embedded content */
+	pos = CMS_get0_content(cms);
+	*pos = os;
+
+	r = 1;
+
+	err:
+	if (rct_cont)
+		BIO_free(rct_cont);
+	if (r)
+		return cms;
+	CMS_ContentInfo_free(cms);
+	return NULL;
+
+	}
+
+CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
+				const EVP_CIPHER *cipher, unsigned int flags)
+	{
+	CMS_ContentInfo *cms;
+	int i;
+	X509 *recip;
+	cms = CMS_EnvelopedData_create(cipher);
+	if (!cms)
+		goto merr;
+	for (i = 0; i < sk_X509_num(certs); i++)
+		{
+		recip = sk_X509_value(certs, i);
+		if (!CMS_add1_recipient_cert(cms, recip, flags))
+			{
+			CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR);
+			goto err;
+			}
+		}
+
+	if(!(flags & CMS_DETACHED))
+		CMS_set_detached(cms, 0);
+
+	if ((flags & (CMS_STREAM|CMS_PARTIAL))
+		|| CMS_final(cms, data, NULL, flags))
+		return cms;
+	else
+		goto err;
+
+	merr:
+	CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE);
+	err:
+	if (cms)
+		CMS_ContentInfo_free(cms);
+	return NULL;
+	}
+
+int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
+	{
+	STACK_OF(CMS_RecipientInfo) *ris;
+	CMS_RecipientInfo *ri;
+	int i, r;
+	int debug = 0;
+	ris = CMS_get0_RecipientInfos(cms);
+	if (ris)
+		debug = cms->d.envelopedData->encryptedContentInfo->debug;
+	for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
+		{
+		ri = sk_CMS_RecipientInfo_value(ris, i);
+		if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_TRANS)
+				continue;
+		/* If we have a cert try matching RecipientInfo
+		 * otherwise try them all.
+		 */
+		if (!cert || (CMS_RecipientInfo_ktri_cert_cmp(ri, cert) == 0))
+			{
+			CMS_RecipientInfo_set0_pkey(ri, pk);
+			r = CMS_RecipientInfo_decrypt(cms, ri);
+			CMS_RecipientInfo_set0_pkey(ri, NULL);
+			if (cert)
+				{
+				/* If not debugging clear any error and
+				 * return success to avoid leaking of
+				 * information useful to MMA
+				 */
+				if (!debug)
+					{
+					ERR_clear_error();
+					return 1;
+					}
+				if (r > 0)
+					return 1;
+				CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY,
+						CMS_R_DECRYPT_ERROR);
+				return 0;
+				}
+			/* If no cert and not debugging don't leave loop
+			 * after first successful decrypt. Always attempt
+			 * to decrypt all recipients to avoid leaking timing
+			 * of a successful decrypt.
+			 */
+			else if (r > 0 && debug)
+				return 1;
+			}
+		}
+	/* If no cert and not debugging always return success */
+	if (!cert && !debug)
+		{
+		ERR_clear_error();
+		return 1;
+		}
+
+	CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT);
+	return 0;
+
+	}
+
+int CMS_decrypt_set1_key(CMS_ContentInfo *cms, 
+				unsigned char *key, size_t keylen,
+				unsigned char *id, size_t idlen)
+	{
+	STACK_OF(CMS_RecipientInfo) *ris;
+	CMS_RecipientInfo *ri;
+	int i, r;
+	ris = CMS_get0_RecipientInfos(cms);
+	for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
+		{
+		ri = sk_CMS_RecipientInfo_value(ris, i);
+		if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK)
+				continue;
+
+		/* If we have an id try matching RecipientInfo
+		 * otherwise try them all.
+		 */
+		if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0))
+			{
+			CMS_RecipientInfo_set0_key(ri, key, keylen);
+			r = CMS_RecipientInfo_decrypt(cms, ri);
+			CMS_RecipientInfo_set0_key(ri, NULL, 0);
+			if (r > 0)
+				return 1;
+			if (id)
+				{
+				CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY,
+						CMS_R_DECRYPT_ERROR);
+				return 0;
+				}
+			ERR_clear_error();
+			}
+		}
+
+	CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_NO_MATCHING_RECIPIENT);
+	return 0;
+
+	}
+
+int CMS_decrypt_set1_password(CMS_ContentInfo *cms, 
+				unsigned char *pass, ossl_ssize_t passlen)
+	{
+	STACK_OF(CMS_RecipientInfo) *ris;
+	CMS_RecipientInfo *ri;
+	int i, r;
+	ris = CMS_get0_RecipientInfos(cms);
+	for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
+		{
+		ri = sk_CMS_RecipientInfo_value(ris, i);
+		if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS)
+				continue;
+		CMS_RecipientInfo_set0_password(ri, pass, passlen);
+		r = CMS_RecipientInfo_decrypt(cms, ri);
+		CMS_RecipientInfo_set0_password(ri, NULL, 0);
+		if (r > 0)
+			return 1;
+		}
+
+	CMSerr(CMS_F_CMS_DECRYPT_SET1_PASSWORD, CMS_R_NO_MATCHING_RECIPIENT);
+	return 0;
+
+	}
+	
+int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
+				BIO *dcont, BIO *out,
+				unsigned int flags)
+	{
+	int r;
+	BIO *cont;
+	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped)
+		{
+		CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA);
+		return 0;
+		}
+	if (!dcont && !check_content(cms))
+		return 0;
+	if (flags & CMS_DEBUG_DECRYPT)
+		cms->d.envelopedData->encryptedContentInfo->debug = 1;
+	else
+		cms->d.envelopedData->encryptedContentInfo->debug = 0;
+	if (!pk && !cert && !dcont && !out)
+		return 1;
+	if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert))
+		return 0;
+	cont = CMS_dataInit(cms, dcont);
+	if (!cont)
+		return 0;
+	r = cms_copy_content(out, cont, flags);
+	do_free_upto(cont, dcont);
+	return r;
+	}
+
+int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags)
+	{
+	BIO *cmsbio;
+	int ret = 0;
+	if (!(cmsbio = CMS_dataInit(cms, dcont)))
+		{
+		CMSerr(CMS_F_CMS_FINAL,ERR_R_MALLOC_FAILURE);
+		return 0;
+		}
+
+	SMIME_crlf_copy(data, cmsbio, flags);
+
+	(void)BIO_flush(cmsbio);
+
+
+        if (!CMS_dataFinal(cms, cmsbio))
+		{
+		CMSerr(CMS_F_CMS_FINAL,CMS_R_CMS_DATAFINAL_ERROR);
+		goto err;
+		}
+
+	ret = 1;
+
+	err:
+	do_free_upto(cmsbio, dcont);
+
+	return ret;
+
+	}
+
+#ifdef ZLIB
+
+int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+							unsigned int flags)
+	{
+	BIO *cont;
+	int r;
+	if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData)
+		{
+		CMSerr(CMS_F_CMS_UNCOMPRESS,
+					CMS_R_TYPE_NOT_COMPRESSED_DATA);
+		return 0;
+		}
+
+	if (!dcont && !check_content(cms))
+		return 0;
+
+	cont = CMS_dataInit(cms, dcont);
+	if (!cont)
+		return 0;
+	r = cms_copy_content(out, cont, flags);
+	do_free_upto(cont, dcont);
+	return r;
+	}
+
+CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
+	{
+	CMS_ContentInfo *cms;
+	if (comp_nid <= 0)
+		comp_nid = NID_zlib_compression;
+	cms = cms_CompressedData_create(comp_nid);
+	if (!cms)
+		return NULL;
+
+	if(!(flags & CMS_DETACHED))
+		CMS_set_detached(cms, 0);
+
+	if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
+		return cms;
+
+	CMS_ContentInfo_free(cms);
+	return NULL;
+	}
+
+#else
+
+int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+							unsigned int flags)
+	{
+	CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+	return 0;
+	}
+
+CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
+	{
+	CMSerr(CMS_F_CMS_COMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+	return NULL;
+	}
+
+#endif
diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c
index 83909c1..0ce4524 100644
--- a/crypto/ec/ec_ameth.c
+++ b/crypto/ec/ec_ameth.c
@@ -88,7 +88,7 @@
 		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/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c
index 175eec5..145807b 100644
--- a/crypto/ec/ec_asn1.c
+++ b/crypto/ec/ec_asn1.c
@@ -89,7 +89,8 @@
 	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 @@
 	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/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c
index 25247b5..de9a0cc 100644
--- a/crypto/ec/ec_lib.c
+++ b/crypto/ec/ec_lib.c
@@ -480,10 +480,10 @@
 	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 @@
 	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/crypto/evp/digest.c b/crypto/evp/digest.c
index 6fc469f..d14e8e4 100644
--- a/crypto/evp/digest.c
+++ b/crypto/evp/digest.c
@@ -366,8 +366,11 @@
 
 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/crypto/evp/e_aes.c b/crypto/evp/e_aes.c
index 1bfb5d9..c7869b6 100644
--- a/crypto/evp/e_aes.c
+++ b/crypto/evp/e_aes.c
@@ -842,7 +842,10 @@
 			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
@@ -1083,14 +1086,17 @@
 			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);
diff --git a/crypto/evp/e_aes_cbc_hmac_sha1.c b/crypto/evp/e_aes_cbc_hmac_sha1.c
index 483e04b..fb2c884 100644
--- a/crypto/evp/e_aes_cbc_hmac_sha1.c
+++ b/crypto/evp/e_aes_cbc_hmac_sha1.c
@@ -328,10 +328,11 @@
 
 				if (res!=SHA_CBLOCK) continue;
 
-				mask = 0-((inp_len+8-j)>>(sizeof(j)*8-1));
+				/* 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-73)>>(sizeof(j)*8-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;
diff --git a/crypto/evp/e_des3.c b/crypto/evp/e_des3.c
index 1e69972..8d7b7de 100644
--- a/crypto/evp/e_des3.c
+++ b/crypto/evp/e_des3.c
@@ -101,7 +101,7 @@
 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 @@
 	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_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/crypto/evp/p5_crpt2.c b/crypto/evp/p5_crpt2.c
index 975d004..fe3c6c8 100644
--- a/crypto/evp/p5_crpt2.c
+++ b/crypto/evp/p5_crpt2.c
@@ -85,19 +85,24 @@
 	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 @@
 		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 @@
 		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/crypto/modes/asm/ghash-alpha.pl b/crypto/modes/asm/ghash-alpha.pl
index 6358b27..aa36029 100644
--- a/crypto/modes/asm/ghash-alpha.pl
+++ b/crypto/modes/asm/ghash-alpha.pl
@@ -266,8 +266,8 @@
 	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 @@
 	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 @@
 .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/crypto/modes/asm/ghash-parisc.pl b/crypto/modes/asm/ghash-parisc.pl
index 8c7454e..d5ad96b 100644
--- a/crypto/modes/asm/ghash-parisc.pl
+++ b/crypto/modes/asm/ghash-parisc.pl
@@ -724,6 +724,7 @@
 		s/cmpb,\*/comb,/;
 		s/,\*/,/;
 	}
+	s/\bbv\b/bve/	if ($SIZE_T==8);
 	print $_,"\n";
 }
 
diff --git a/crypto/modes/cbc128.c b/crypto/modes/cbc128.c
index 3d3782c..0e54f75 100644
--- a/crypto/modes/cbc128.c
+++ b/crypto/modes/cbc128.c
@@ -117,7 +117,7 @@
 			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 @@
 				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 @@
 				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/crypto/modes/ccm128.c b/crypto/modes/ccm128.c
index c9b35e5..3ce11d0 100644
--- a/crypto/modes/ccm128.c
+++ b/crypto/modes/ccm128.c
@@ -87,7 +87,7 @@
 		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/crypto/modes/gcm128.c b/crypto/modes/gcm128.c
index 0e6ff8b..250063d 100644
--- a/crypto/modes/gcm128.c
+++ b/crypto/modes/gcm128.c
@@ -941,15 +941,17 @@
 		    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)
 				PUTU32(ctx->Yi.c+12,ctr);
 			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 +963,17 @@
 		    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)
 				PUTU32(ctx->Yi.c+12,ctr);
 			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 +982,18 @@
 		}
 #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)
 				PUTU32(ctx->Yi.c+12,ctr);
 			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;
@@ -1091,15 +1097,17 @@
 
 		    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)
 				PUTU32(ctx->Yi.c+12,ctr);
 			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 +1117,17 @@
 		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)
 				PUTU32(ctx->Yi.c+12,ctr);
 			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 +1135,19 @@
 		}
 #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)
 				PUTU32(ctx->Yi.c+12,ctr);
 			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;
@@ -1669,6 +1682,46 @@
 			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 +1766,8 @@
 	TEST_CASE(16);
 	TEST_CASE(17);
 	TEST_CASE(18);
+	TEST_CASE(19);
+	TEST_CASE(20);
 
 #ifdef OPENSSL_CPUID_OBJ
 	{
@@ -1743,11 +1798,16 @@
 			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/crypto/modes/modes_lcl.h b/crypto/modes/modes_lcl.h
index b6dc3c3..9d83e12 100644
--- a/crypto/modes/modes_lcl.h
+++ b/crypto/modes/modes_lcl.h
@@ -29,10 +29,7 @@
 #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 @@
 
 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/crypto/opensslconf-32.h b/crypto/opensslconf-32.h
new file mode 100644
index 0000000..d662548
--- /dev/null
+++ b/crypto/opensslconf-32.h
@@ -0,0 +1,316 @@
+/* opensslconf.h */
+/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
+
+/* OpenSSL was configured with the following options: */
+#ifndef OPENSSL_DOING_MAKEDEPEND
+
+
+#ifndef OPENSSL_NO_CAMELLIA
+# define OPENSSL_NO_CAMELLIA
+#endif
+#ifndef OPENSSL_NO_CAPIENG
+# define OPENSSL_NO_CAPIENG
+#endif
+#ifndef OPENSSL_NO_CAST
+# define OPENSSL_NO_CAST
+#endif
+#ifndef OPENSSL_NO_DTLS1
+# define OPENSSL_NO_DTLS1
+#endif
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+# define OPENSSL_NO_EC_NISTP_64_GCC_128
+#endif
+#ifndef OPENSSL_NO_GMP
+# define OPENSSL_NO_GMP
+#endif
+#ifndef OPENSSL_NO_GOST
+# define OPENSSL_NO_GOST
+#endif
+#ifndef OPENSSL_NO_HEARTBEATS
+# define OPENSSL_NO_HEARTBEATS
+#endif
+#ifndef OPENSSL_NO_IDEA
+# define OPENSSL_NO_IDEA
+#endif
+#ifndef OPENSSL_NO_JPAKE
+# define OPENSSL_NO_JPAKE
+#endif
+#ifndef OPENSSL_NO_KRB5
+# define OPENSSL_NO_KRB5
+#endif
+#ifndef OPENSSL_NO_MD2
+# define OPENSSL_NO_MD2
+#endif
+#ifndef OPENSSL_NO_MDC2
+# define OPENSSL_NO_MDC2
+#endif
+#ifndef OPENSSL_NO_RC5
+# define OPENSSL_NO_RC5
+#endif
+#ifndef OPENSSL_NO_RDRAND
+# define OPENSSL_NO_RDRAND
+#endif
+#ifndef OPENSSL_NO_RFC3779
+# define OPENSSL_NO_RFC3779
+#endif
+#ifndef OPENSSL_NO_RSAX
+# define OPENSSL_NO_RSAX
+#endif
+#ifndef OPENSSL_NO_SCTP
+# define OPENSSL_NO_SCTP
+#endif
+#ifndef OPENSSL_NO_SEED
+# define OPENSSL_NO_SEED
+#endif
+#ifndef OPENSSL_NO_SHA0
+# define OPENSSL_NO_SHA0
+#endif
+#ifndef OPENSSL_NO_STATIC_ENGINE
+# define OPENSSL_NO_STATIC_ENGINE
+#endif
+#ifndef OPENSSL_NO_STORE
+# define OPENSSL_NO_STORE
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+# define OPENSSL_NO_WHIRLPOOL
+#endif
+
+#endif /* OPENSSL_DOING_MAKEDEPEND */
+
+#ifndef OPENSSL_THREADS
+# define OPENSSL_THREADS
+#endif
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+# define OPENSSL_NO_DYNAMIC_ENGINE
+#endif
+
+/* The OPENSSL_NO_* macros are also defined as NO_* if the application
+   asks for it.  This is a transient feature that is provided for those
+   who haven't had the time to do the appropriate changes in their
+   applications.  */
+#ifdef OPENSSL_ALGORITHM_DEFINES
+# if defined(OPENSSL_NO_CAMELLIA) && !defined(NO_CAMELLIA)
+#  define NO_CAMELLIA
+# endif
+# if defined(OPENSSL_NO_CAPIENG) && !defined(NO_CAPIENG)
+#  define NO_CAPIENG
+# endif
+# if defined(OPENSSL_NO_CAST) && !defined(NO_CAST)
+#  define NO_CAST
+# endif
+# if defined(OPENSSL_NO_DTLS1) && !defined(NO_DTLS1)
+#  define NO_DTLS1
+# endif
+# if defined(OPENSSL_NO_EC_NISTP_64_GCC_128) && !defined(NO_EC_NISTP_64_GCC_128)
+#  define NO_EC_NISTP_64_GCC_128
+# endif
+# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
+#  define NO_GMP
+# endif
+# if defined(OPENSSL_NO_GOST) && !defined(NO_GOST)
+#  define NO_GOST
+# endif
+# if defined(OPENSSL_NO_HEARTBEATS) && !defined(NO_HEARTBEATS)
+#  define NO_HEARTBEATS
+# endif
+# if defined(OPENSSL_NO_IDEA) && !defined(NO_IDEA)
+#  define NO_IDEA
+# endif
+# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE)
+#  define NO_JPAKE
+# endif
+# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5)
+#  define NO_KRB5
+# endif
+# if defined(OPENSSL_NO_MD2) && !defined(NO_MD2)
+#  define NO_MD2
+# endif
+# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
+#  define NO_MDC2
+# endif
+# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
+#  define NO_RC5
+# endif
+# if defined(OPENSSL_NO_RDRAND) && !defined(NO_RDRAND)
+#  define NO_RDRAND
+# endif
+# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779)
+#  define NO_RFC3779
+# endif
+# if defined(OPENSSL_NO_RSAX) && !defined(NO_RSAX)
+#  define NO_RSAX
+# endif
+# if defined(OPENSSL_NO_SCTP) && !defined(NO_SCTP)
+#  define NO_SCTP
+# endif
+# if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)
+#  define NO_SEED
+# endif
+# if defined(OPENSSL_NO_SHA0) && !defined(NO_SHA0)
+#  define NO_SHA0
+# endif
+# if defined(OPENSSL_NO_STATIC_ENGINE) && !defined(NO_STATIC_ENGINE)
+#  define NO_STATIC_ENGINE
+# endif
+# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE)
+#  define NO_STORE
+# endif
+# if defined(OPENSSL_NO_WHIRLPOOL) && !defined(NO_WHIRLPOOL)
+#  define NO_WHIRLPOOL
+# endif
+#endif
+
+/* crypto/opensslconf.h.in */
+
+/* Generate 80386 code? */
+#undef I386_ONLY
+
+#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
+#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
+#define ENGINESDIR "/usr/local/ssl/lib/engines"
+#define OPENSSLDIR "/usr/local/ssl"
+#endif
+#endif
+
+#undef OPENSSL_UNISTD
+#define OPENSSL_UNISTD <unistd.h>
+
+#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
+#define IDEA_INT unsigned int
+#endif
+
+#if defined(HEADER_MD2_H) && !defined(MD2_INT)
+#define MD2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC2_H) && !defined(RC2_INT)
+/* I need to put in a mod for the alpha - eay */
+#define RC2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC4_H)
+#if !defined(RC4_INT)
+/* using int types make the structure larger but make the code faster
+ * on most boxes I have tested - up to %20 faster. */
+/*
+ * I don't know what does "most" mean, but declaring "int" is a must on:
+ * - Intel P6 because partial register stalls are very expensive;
+ * - elder Alpha because it lacks byte load/store instructions;
+ */
+#define RC4_INT unsigned char
+#endif
+#if !defined(RC4_CHUNK)
+/*
+ * This enables code handling data aligned at natural CPU word
+ * boundary. See crypto/rc4/rc4_enc.c for further details.
+ */
+#define RC4_CHUNK unsigned long
+#endif
+#endif
+
+#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
+ * %20 speed up (longs are 8 bytes, int's are 4). */
+#ifndef DES_LONG
+#define DES_LONG unsigned int
+#endif
+#endif
+
+#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
+#define CONFIG_HEADER_BN_H
+#define BN_LLONG
+
+/* Should we define BN_DIV2W here? */
+
+/* Only one for the following should be defined */
+#undef SIXTY_FOUR_BIT_LONG
+#undef SIXTY_FOUR_BIT
+#define THIRTY_TWO_BIT
+#endif
+
+#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
+#define CONFIG_HEADER_RC4_LOCL_H
+/* if this is defined data[i] is used instead of *data, this is a %20
+ * speedup on x86 */
+#undef RC4_INDEX
+#endif
+
+#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
+#define CONFIG_HEADER_BF_LOCL_H
+#define BF_PTR
+#endif /* HEADER_BF_LOCL_H */
+
+#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
+#define CONFIG_HEADER_DES_LOCL_H
+#ifndef DES_DEFAULT_OPTIONS
+/* the following is tweaked from a config script, that is why it is a
+ * protected undef/define */
+#ifndef DES_PTR
+#undef DES_PTR
+#endif
+
+/* This helps C compiler generate the correct code for multiple functional
+ * units.  It reduces register dependancies at the expense of 2 more
+ * registers */
+#ifndef DES_RISC1
+#undef DES_RISC1
+#endif
+
+#ifndef DES_RISC2
+#undef DES_RISC2
+#endif
+
+#if defined(DES_RISC1) && defined(DES_RISC2)
+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
+#endif
+
+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
+ * Very mucy CPU dependant */
+#ifndef DES_UNROLL
+#define DES_UNROLL
+#endif
+
+/* These default values were supplied by
+ * Peter Gutman <pgut001@cs.auckland.ac.nz>
+ * They are only used if nothing else has been defined */
+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
+/* Special defines which change the way the code is built depending on the
+   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
+   even newer MIPS CPU's, but at the moment one size fits all for
+   optimization options.  Older Sparc's work better with only UNROLL, but
+   there's no way to tell at compile time what it is you're running on */
+ 
+#if defined( sun )		/* Newer Sparc's */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#elif defined( __ultrix )	/* Older MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined( __osf1__ )	/* Alpha */
+#  define DES_PTR
+#  define DES_RISC2
+#elif defined ( _AIX )		/* RS6000 */
+  /* Unknown */
+#elif defined( __hpux )		/* HP-PA */
+  /* Unknown */
+#elif defined( __aux )		/* 68K */
+  /* Unknown */
+#elif defined( __dgux )		/* 88K (but P6 in latest boxes) */
+#  define DES_UNROLL
+#elif defined( __sgi )		/* Newer MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined(i386) || defined(__i386__)	/* x86 boxes, should be gcc */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#endif /* Systems-specific speed defines */
+#endif
+
+#endif /* DES_DEFAULT_OPTIONS */
+#endif /* HEADER_DES_LOCL_H */
diff --git a/crypto/opensslconf-64.h b/crypto/opensslconf-64.h
new file mode 100644
index 0000000..70c5a2c
--- /dev/null
+++ b/crypto/opensslconf-64.h
@@ -0,0 +1,316 @@
+/* opensslconf.h */
+/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
+
+/* OpenSSL was configured with the following options: */
+#ifndef OPENSSL_DOING_MAKEDEPEND
+
+
+#ifndef OPENSSL_NO_CAMELLIA
+# define OPENSSL_NO_CAMELLIA
+#endif
+#ifndef OPENSSL_NO_CAPIENG
+# define OPENSSL_NO_CAPIENG
+#endif
+#ifndef OPENSSL_NO_CAST
+# define OPENSSL_NO_CAST
+#endif
+#ifndef OPENSSL_NO_DTLS1
+# define OPENSSL_NO_DTLS1
+#endif
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+# define OPENSSL_NO_EC_NISTP_64_GCC_128
+#endif
+#ifndef OPENSSL_NO_GMP
+# define OPENSSL_NO_GMP
+#endif
+#ifndef OPENSSL_NO_GOST
+# define OPENSSL_NO_GOST
+#endif
+#ifndef OPENSSL_NO_HEARTBEATS
+# define OPENSSL_NO_HEARTBEATS
+#endif
+#ifndef OPENSSL_NO_IDEA
+# define OPENSSL_NO_IDEA
+#endif
+#ifndef OPENSSL_NO_JPAKE
+# define OPENSSL_NO_JPAKE
+#endif
+#ifndef OPENSSL_NO_KRB5
+# define OPENSSL_NO_KRB5
+#endif
+#ifndef OPENSSL_NO_MD2
+# define OPENSSL_NO_MD2
+#endif
+#ifndef OPENSSL_NO_MDC2
+# define OPENSSL_NO_MDC2
+#endif
+#ifndef OPENSSL_NO_RC5
+# define OPENSSL_NO_RC5
+#endif
+#ifndef OPENSSL_NO_RDRAND
+# define OPENSSL_NO_RDRAND
+#endif
+#ifndef OPENSSL_NO_RFC3779
+# define OPENSSL_NO_RFC3779
+#endif
+#ifndef OPENSSL_NO_RSAX
+# define OPENSSL_NO_RSAX
+#endif
+#ifndef OPENSSL_NO_SCTP
+# define OPENSSL_NO_SCTP
+#endif
+#ifndef OPENSSL_NO_SEED
+# define OPENSSL_NO_SEED
+#endif
+#ifndef OPENSSL_NO_SHA0
+# define OPENSSL_NO_SHA0
+#endif
+#ifndef OPENSSL_NO_STATIC_ENGINE
+# define OPENSSL_NO_STATIC_ENGINE
+#endif
+#ifndef OPENSSL_NO_STORE
+# define OPENSSL_NO_STORE
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+# define OPENSSL_NO_WHIRLPOOL
+#endif
+
+#endif /* OPENSSL_DOING_MAKEDEPEND */
+
+#ifndef OPENSSL_THREADS
+# define OPENSSL_THREADS
+#endif
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+# define OPENSSL_NO_DYNAMIC_ENGINE
+#endif
+
+/* The OPENSSL_NO_* macros are also defined as NO_* if the application
+   asks for it.  This is a transient feature that is provided for those
+   who haven't had the time to do the appropriate changes in their
+   applications.  */
+#ifdef OPENSSL_ALGORITHM_DEFINES
+# if defined(OPENSSL_NO_CAMELLIA) && !defined(NO_CAMELLIA)
+#  define NO_CAMELLIA
+# endif
+# if defined(OPENSSL_NO_CAPIENG) && !defined(NO_CAPIENG)
+#  define NO_CAPIENG
+# endif
+# if defined(OPENSSL_NO_CAST) && !defined(NO_CAST)
+#  define NO_CAST
+# endif
+# if defined(OPENSSL_NO_DTLS1) && !defined(NO_DTLS1)
+#  define NO_DTLS1
+# endif
+# if defined(OPENSSL_NO_EC_NISTP_64_GCC_128) && !defined(NO_EC_NISTP_64_GCC_128)
+#  define NO_EC_NISTP_64_GCC_128
+# endif
+# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
+#  define NO_GMP
+# endif
+# if defined(OPENSSL_NO_GOST) && !defined(NO_GOST)
+#  define NO_GOST
+# endif
+# if defined(OPENSSL_NO_HEARTBEATS) && !defined(NO_HEARTBEATS)
+#  define NO_HEARTBEATS
+# endif
+# if defined(OPENSSL_NO_IDEA) && !defined(NO_IDEA)
+#  define NO_IDEA
+# endif
+# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE)
+#  define NO_JPAKE
+# endif
+# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5)
+#  define NO_KRB5
+# endif
+# if defined(OPENSSL_NO_MD2) && !defined(NO_MD2)
+#  define NO_MD2
+# endif
+# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
+#  define NO_MDC2
+# endif
+# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
+#  define NO_RC5
+# endif
+# if defined(OPENSSL_NO_RDRAND) && !defined(NO_RDRAND)
+#  define NO_RDRAND
+# endif
+# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779)
+#  define NO_RFC3779
+# endif
+# if defined(OPENSSL_NO_RSAX) && !defined(NO_RSAX)
+#  define NO_RSAX
+# endif
+# if defined(OPENSSL_NO_SCTP) && !defined(NO_SCTP)
+#  define NO_SCTP
+# endif
+# if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)
+#  define NO_SEED
+# endif
+# if defined(OPENSSL_NO_SHA0) && !defined(NO_SHA0)
+#  define NO_SHA0
+# endif
+# if defined(OPENSSL_NO_STATIC_ENGINE) && !defined(NO_STATIC_ENGINE)
+#  define NO_STATIC_ENGINE
+# endif
+# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE)
+#  define NO_STORE
+# endif
+# if defined(OPENSSL_NO_WHIRLPOOL) && !defined(NO_WHIRLPOOL)
+#  define NO_WHIRLPOOL
+# endif
+#endif
+
+/* crypto/opensslconf.h.in */
+
+/* Generate 80386 code? */
+#undef I386_ONLY
+
+#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
+#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
+#define ENGINESDIR "/usr/local/ssl/lib/engines"
+#define OPENSSLDIR "/usr/local/ssl"
+#endif
+#endif
+
+#undef OPENSSL_UNISTD
+#define OPENSSL_UNISTD <unistd.h>
+
+#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
+#define IDEA_INT unsigned int
+#endif
+
+#if defined(HEADER_MD2_H) && !defined(MD2_INT)
+#define MD2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC2_H) && !defined(RC2_INT)
+/* I need to put in a mod for the alpha - eay */
+#define RC2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC4_H)
+#if !defined(RC4_INT)
+/* using int types make the structure larger but make the code faster
+ * on most boxes I have tested - up to %20 faster. */
+/*
+ * I don't know what does "most" mean, but declaring "int" is a must on:
+ * - Intel P6 because partial register stalls are very expensive;
+ * - elder Alpha because it lacks byte load/store instructions;
+ */
+#define RC4_INT unsigned char
+#endif
+#if !defined(RC4_CHUNK)
+/*
+ * This enables code handling data aligned at natural CPU word
+ * boundary. See crypto/rc4/rc4_enc.c for further details.
+ */
+#define RC4_CHUNK unsigned long
+#endif
+#endif
+
+#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
+ * %20 speed up (longs are 8 bytes, int's are 4). */
+#ifndef DES_LONG
+#define DES_LONG unsigned int
+#endif
+#endif
+
+#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
+#define CONFIG_HEADER_BN_H
+#undef BN_LLONG
+
+/* Should we define BN_DIV2W here? */
+
+/* Only one for the following should be defined */
+#define SIXTY_FOUR_BIT_LONG
+#undef SIXTY_FOUR_BIT
+#undef THIRTY_TWO_BIT
+#endif
+
+#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
+#define CONFIG_HEADER_RC4_LOCL_H
+/* if this is defined data[i] is used instead of *data, this is a %20
+ * speedup on x86 */
+#undef RC4_INDEX
+#endif
+
+#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
+#define CONFIG_HEADER_BF_LOCL_H
+#define BF_PTR
+#endif /* HEADER_BF_LOCL_H */
+
+#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
+#define CONFIG_HEADER_DES_LOCL_H
+#ifndef DES_DEFAULT_OPTIONS
+/* the following is tweaked from a config script, that is why it is a
+ * protected undef/define */
+#ifndef DES_PTR
+#undef DES_PTR
+#endif
+
+/* This helps C compiler generate the correct code for multiple functional
+ * units.  It reduces register dependancies at the expense of 2 more
+ * registers */
+#ifndef DES_RISC1
+#undef DES_RISC1
+#endif
+
+#ifndef DES_RISC2
+#undef DES_RISC2
+#endif
+
+#if defined(DES_RISC1) && defined(DES_RISC2)
+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
+#endif
+
+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
+ * Very mucy CPU dependant */
+#ifndef DES_UNROLL
+#define DES_UNROLL
+#endif
+
+/* These default values were supplied by
+ * Peter Gutman <pgut001@cs.auckland.ac.nz>
+ * They are only used if nothing else has been defined */
+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
+/* Special defines which change the way the code is built depending on the
+   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
+   even newer MIPS CPU's, but at the moment one size fits all for
+   optimization options.  Older Sparc's work better with only UNROLL, but
+   there's no way to tell at compile time what it is you're running on */
+ 
+#if defined( sun )		/* Newer Sparc's */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#elif defined( __ultrix )	/* Older MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined( __osf1__ )	/* Alpha */
+#  define DES_PTR
+#  define DES_RISC2
+#elif defined ( _AIX )		/* RS6000 */
+  /* Unknown */
+#elif defined( __hpux )		/* HP-PA */
+  /* Unknown */
+#elif defined( __aux )		/* 68K */
+  /* Unknown */
+#elif defined( __dgux )		/* 88K (but P6 in latest boxes) */
+#  define DES_UNROLL
+#elif defined( __sgi )		/* Newer MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined(i386) || defined(__i386__)	/* x86 boxes, should be gcc */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#endif /* Systems-specific speed defines */
+#endif
+
+#endif /* DES_DEFAULT_OPTIONS */
+#endif /* HEADER_DES_LOCL_H */
diff --git a/crypto/opensslconf.h b/crypto/opensslconf.h
index 6149d3e..d00590b 100644
--- a/crypto/opensslconf.h
+++ b/crypto/opensslconf.h
@@ -1,322 +1,6 @@
-/* opensslconf.h */
-/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
-
-/* OpenSSL was configured with the following options: */
-#ifndef OPENSSL_DOING_MAKEDEPEND
-
-
-#ifndef OPENSSL_NO_CAMELLIA
-# define OPENSSL_NO_CAMELLIA
+// Auto-generated - DO NOT EDIT!
+#if defined(__LP64__)
+#include "opensslconf-64.h"
+#else
+#include "opensslconf-32.h"
 #endif
-#ifndef OPENSSL_NO_CAPIENG
-# define OPENSSL_NO_CAPIENG
-#endif
-#ifndef OPENSSL_NO_CAST
-# define OPENSSL_NO_CAST
-#endif
-#ifndef OPENSSL_NO_CMS
-# define OPENSSL_NO_CMS
-#endif
-#ifndef OPENSSL_NO_DTLS1
-# define OPENSSL_NO_DTLS1
-#endif
-#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
-# define OPENSSL_NO_EC_NISTP_64_GCC_128
-#endif
-#ifndef OPENSSL_NO_GMP
-# define OPENSSL_NO_GMP
-#endif
-#ifndef OPENSSL_NO_GOST
-# define OPENSSL_NO_GOST
-#endif
-#ifndef OPENSSL_NO_HEARTBEATS
-# define OPENSSL_NO_HEARTBEATS
-#endif
-#ifndef OPENSSL_NO_IDEA
-# define OPENSSL_NO_IDEA
-#endif
-#ifndef OPENSSL_NO_JPAKE
-# define OPENSSL_NO_JPAKE
-#endif
-#ifndef OPENSSL_NO_KRB5
-# define OPENSSL_NO_KRB5
-#endif
-#ifndef OPENSSL_NO_MD2
-# define OPENSSL_NO_MD2
-#endif
-#ifndef OPENSSL_NO_MDC2
-# define OPENSSL_NO_MDC2
-#endif
-#ifndef OPENSSL_NO_RC5
-# define OPENSSL_NO_RC5
-#endif
-#ifndef OPENSSL_NO_RDRAND
-# define OPENSSL_NO_RDRAND
-#endif
-#ifndef OPENSSL_NO_RFC3779
-# define OPENSSL_NO_RFC3779
-#endif
-#ifndef OPENSSL_NO_RSAX
-# define OPENSSL_NO_RSAX
-#endif
-#ifndef OPENSSL_NO_SCTP
-# define OPENSSL_NO_SCTP
-#endif
-#ifndef OPENSSL_NO_SEED
-# define OPENSSL_NO_SEED
-#endif
-#ifndef OPENSSL_NO_SHA0
-# define OPENSSL_NO_SHA0
-#endif
-#ifndef OPENSSL_NO_STATIC_ENGINE
-# define OPENSSL_NO_STATIC_ENGINE
-#endif
-#ifndef OPENSSL_NO_STORE
-# define OPENSSL_NO_STORE
-#endif
-#ifndef OPENSSL_NO_WHIRLPOOL
-# define OPENSSL_NO_WHIRLPOOL
-#endif
-
-#endif /* OPENSSL_DOING_MAKEDEPEND */
-
-#ifndef OPENSSL_THREADS
-# define OPENSSL_THREADS
-#endif
-#ifndef OPENSSL_NO_DYNAMIC_ENGINE
-# define OPENSSL_NO_DYNAMIC_ENGINE
-#endif
-
-/* The OPENSSL_NO_* macros are also defined as NO_* if the application
-   asks for it.  This is a transient feature that is provided for those
-   who haven't had the time to do the appropriate changes in their
-   applications.  */
-#ifdef OPENSSL_ALGORITHM_DEFINES
-# if defined(OPENSSL_NO_CAMELLIA) && !defined(NO_CAMELLIA)
-#  define NO_CAMELLIA
-# endif
-# if defined(OPENSSL_NO_CAPIENG) && !defined(NO_CAPIENG)
-#  define NO_CAPIENG
-# endif
-# if defined(OPENSSL_NO_CAST) && !defined(NO_CAST)
-#  define NO_CAST
-# endif
-# if defined(OPENSSL_NO_CMS) && !defined(NO_CMS)
-#  define NO_CMS
-# endif
-# if defined(OPENSSL_NO_DTLS1) && !defined(NO_DTLS1)
-#  define NO_DTLS1
-# endif
-# if defined(OPENSSL_NO_EC_NISTP_64_GCC_128) && !defined(NO_EC_NISTP_64_GCC_128)
-#  define NO_EC_NISTP_64_GCC_128
-# endif
-# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
-#  define NO_GMP
-# endif
-# if defined(OPENSSL_NO_GOST) && !defined(NO_GOST)
-#  define NO_GOST
-# endif
-# if defined(OPENSSL_NO_HEARTBEATS) && !defined(NO_HEARTBEATS)
-#  define NO_HEARTBEATS
-# endif
-# if defined(OPENSSL_NO_IDEA) && !defined(NO_IDEA)
-#  define NO_IDEA
-# endif
-# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE)
-#  define NO_JPAKE
-# endif
-# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5)
-#  define NO_KRB5
-# endif
-# if defined(OPENSSL_NO_MD2) && !defined(NO_MD2)
-#  define NO_MD2
-# endif
-# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
-#  define NO_MDC2
-# endif
-# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
-#  define NO_RC5
-# endif
-# if defined(OPENSSL_NO_RDRAND) && !defined(NO_RDRAND)
-#  define NO_RDRAND
-# endif
-# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779)
-#  define NO_RFC3779
-# endif
-# if defined(OPENSSL_NO_RSAX) && !defined(NO_RSAX)
-#  define NO_RSAX
-# endif
-# if defined(OPENSSL_NO_SCTP) && !defined(NO_SCTP)
-#  define NO_SCTP
-# endif
-# if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)
-#  define NO_SEED
-# endif
-# if defined(OPENSSL_NO_SHA0) && !defined(NO_SHA0)
-#  define NO_SHA0
-# endif
-# if defined(OPENSSL_NO_STATIC_ENGINE) && !defined(NO_STATIC_ENGINE)
-#  define NO_STATIC_ENGINE
-# endif
-# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE)
-#  define NO_STORE
-# endif
-# if defined(OPENSSL_NO_WHIRLPOOL) && !defined(NO_WHIRLPOOL)
-#  define NO_WHIRLPOOL
-# endif
-#endif
-
-/* crypto/opensslconf.h.in */
-
-/* Generate 80386 code? */
-#undef I386_ONLY
-
-#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
-#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
-#define ENGINESDIR "/usr/local/ssl/lib/engines"
-#define OPENSSLDIR "/usr/local/ssl"
-#endif
-#endif
-
-#undef OPENSSL_UNISTD
-#define OPENSSL_UNISTD <unistd.h>
-
-#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
-
-#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
-#define IDEA_INT unsigned int
-#endif
-
-#if defined(HEADER_MD2_H) && !defined(MD2_INT)
-#define MD2_INT unsigned int
-#endif
-
-#if defined(HEADER_RC2_H) && !defined(RC2_INT)
-/* I need to put in a mod for the alpha - eay */
-#define RC2_INT unsigned int
-#endif
-
-#if defined(HEADER_RC4_H)
-#if !defined(RC4_INT)
-/* using int types make the structure larger but make the code faster
- * on most boxes I have tested - up to %20 faster. */
-/*
- * I don't know what does "most" mean, but declaring "int" is a must on:
- * - Intel P6 because partial register stalls are very expensive;
- * - elder Alpha because it lacks byte load/store instructions;
- */
-#define RC4_INT unsigned char
-#endif
-#if !defined(RC4_CHUNK)
-/*
- * This enables code handling data aligned at natural CPU word
- * boundary. See crypto/rc4/rc4_enc.c for further details.
- */
-#define RC4_CHUNK unsigned long
-#endif
-#endif
-
-#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
-/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
- * %20 speed up (longs are 8 bytes, int's are 4). */
-#ifndef DES_LONG
-#define DES_LONG unsigned int
-#endif
-#endif
-
-#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
-#define CONFIG_HEADER_BN_H
-#define BN_LLONG
-
-/* Should we define BN_DIV2W here? */
-
-/* Only one for the following should be defined */
-#undef SIXTY_FOUR_BIT_LONG
-#undef SIXTY_FOUR_BIT
-#define THIRTY_TWO_BIT
-#endif
-
-#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
-#define CONFIG_HEADER_RC4_LOCL_H
-/* if this is defined data[i] is used instead of *data, this is a %20
- * speedup on x86 */
-#undef RC4_INDEX
-#endif
-
-#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
-#define CONFIG_HEADER_BF_LOCL_H
-#define BF_PTR
-#endif /* HEADER_BF_LOCL_H */
-
-#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
-#define CONFIG_HEADER_DES_LOCL_H
-#ifndef DES_DEFAULT_OPTIONS
-/* the following is tweaked from a config script, that is why it is a
- * protected undef/define */
-#ifndef DES_PTR
-#undef DES_PTR
-#endif
-
-/* This helps C compiler generate the correct code for multiple functional
- * units.  It reduces register dependancies at the expense of 2 more
- * registers */
-#ifndef DES_RISC1
-#undef DES_RISC1
-#endif
-
-#ifndef DES_RISC2
-#undef DES_RISC2
-#endif
-
-#if defined(DES_RISC1) && defined(DES_RISC2)
-YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
-#endif
-
-/* Unroll the inner loop, this sometimes helps, sometimes hinders.
- * Very mucy CPU dependant */
-#ifndef DES_UNROLL
-#define DES_UNROLL
-#endif
-
-/* These default values were supplied by
- * Peter Gutman <pgut001@cs.auckland.ac.nz>
- * They are only used if nothing else has been defined */
-#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
-/* Special defines which change the way the code is built depending on the
-   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
-   even newer MIPS CPU's, but at the moment one size fits all for
-   optimization options.  Older Sparc's work better with only UNROLL, but
-   there's no way to tell at compile time what it is you're running on */
- 
-#if defined( sun )		/* Newer Sparc's */
-#  define DES_PTR
-#  define DES_RISC1
-#  define DES_UNROLL
-#elif defined( __ultrix )	/* Older MIPS */
-#  define DES_PTR
-#  define DES_RISC2
-#  define DES_UNROLL
-#elif defined( __osf1__ )	/* Alpha */
-#  define DES_PTR
-#  define DES_RISC2
-#elif defined ( _AIX )		/* RS6000 */
-  /* Unknown */
-#elif defined( __hpux )		/* HP-PA */
-  /* Unknown */
-#elif defined( __aux )		/* 68K */
-  /* Unknown */
-#elif defined( __dgux )		/* 88K (but P6 in latest boxes) */
-#  define DES_UNROLL
-#elif defined( __sgi )		/* Newer MIPS */
-#  define DES_PTR
-#  define DES_RISC2
-#  define DES_UNROLL
-#elif defined(i386) || defined(__i386__)	/* x86 boxes, should be gcc */
-#  define DES_PTR
-#  define DES_RISC1
-#  define DES_UNROLL
-#endif /* Systems-specific speed defines */
-#endif
-
-#endif /* DES_DEFAULT_OPTIONS */
-#endif /* HEADER_DES_LOCL_H */
diff --git a/crypto/opensslv.h b/crypto/opensslv.h
index 5bc8e53..b27a5bb 100644
--- a/crypto/opensslv.h
+++ b/crypto/opensslv.h
@@ -25,11 +25,11 @@
  * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
  *  major minor fix final patch/beta)
  */
-#define OPENSSL_VERSION_NUMBER	0x1000105fL
+#define OPENSSL_VERSION_NUMBER	0x1000106fL
 #ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1e-fips 11 Feb 2013"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1f-fips 6 Jan 2014"
 #else
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1e 11 Feb 2013"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1f 6 Jan 2014"
 #endif
 #define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
 
diff --git a/crypto/pariscid.pl b/crypto/pariscid.pl
index 477ec9b..bfc56fd 100644
--- a/crypto/pariscid.pl
+++ b/crypto/pariscid.pl
@@ -97,33 +97,33 @@
 	.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 @@
 	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 @@
 	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 @@
 	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 @@
 
 	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/crypto/pem/pem_info.c b/crypto/pem/pem_info.c
index 1b2be52..cc7f24a 100644
--- a/crypto/pem/pem_info.c
+++ b/crypto/pem/pem_info.c
@@ -167,6 +167,7 @@
 #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/crypto/pkcs12/p12_crt.c b/crypto/pkcs12/p12_crt.c
index 96b131d..a34915d 100644
--- a/crypto/pkcs12/p12_crt.c
+++ b/crypto/pkcs12/p12_crt.c
@@ -90,7 +90,14 @@
 
 	/* 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/crypto/rand/md_rand.c b/crypto/rand/md_rand.c
index 1e3bcb9..dd29163 100644
--- a/crypto/rand/md_rand.c
+++ b/crypto/rand/md_rand.c
@@ -380,8 +380,11 @@
 	 * are fed into the hash function and the results are kept in the
 	 * global 'md'.
 	 */
-
-	CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+#ifdef OPENSSL_FIPS
+	/* NB: in FIPS mode we are already under a lock */
+	if (!FIPS_mode())
+#endif
+		CRYPTO_w_lock(CRYPTO_LOCK_RAND);
 
 	/* prevent ssleay_rand_bytes() from trying to obtain the lock again */
 	CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
@@ -460,7 +463,10 @@
 
 	/* before unlocking, we must clear 'crypto_lock_rand' */
 	crypto_lock_rand = 0;
-	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+#ifdef OPENSSL_FIPS
+	if (!FIPS_mode())
+#endif
+		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
 
 	while (num > 0)
 		{
@@ -512,10 +518,16 @@
 	MD_Init(&m);
 	MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
 	MD_Update(&m,local_md,MD_DIGEST_LENGTH);
-	CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+#ifdef OPENSSL_FIPS
+	if (!FIPS_mode())
+#endif
+		CRYPTO_w_lock(CRYPTO_LOCK_RAND);
 	MD_Update(&m,md,MD_DIGEST_LENGTH);
 	MD_Final(&m,md);
-	CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+#ifdef OPENSSL_FIPS
+	if (!FIPS_mode())
+#endif
+		CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
 
 	EVP_MD_CTX_cleanup(&m);
 	if (ok)
diff --git a/crypto/rand/rand.h b/crypto/rand/rand.h
index dc8fcf9..bb5520e 100644
--- a/crypto/rand/rand.h
+++ b/crypto/rand/rand.h
@@ -138,6 +138,7 @@
 #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/crypto/rand/rand_err.c b/crypto/rand/rand_err.c
index b8586c8..c4c80fc 100644
--- a/crypto/rand/rand_err.c
+++ b/crypto/rand/rand_err.c
@@ -78,6 +78,7 @@
 
 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/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c
index 476a0cd..5ac0e14 100644
--- a/crypto/rand/rand_lib.c
+++ b/crypto/rand/rand_lib.c
@@ -269,6 +269,14 @@
 	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/crypto/rc4/asm/rc4-parisc.pl b/crypto/rc4/asm/rc4-parisc.pl
index 9165067..ad7e656 100644
--- a/crypto/rc4/asm/rc4-parisc.pl
+++ b/crypto/rc4/asm/rc4-parisc.pl
@@ -307,7 +307,8 @@
 	.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/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c
index 2460910..5a2062f 100644
--- a/crypto/rsa/rsa_ameth.c
+++ b/crypto/rsa/rsa_ameth.c
@@ -351,27 +351,27 @@
 
 	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/crypto/rsa/rsa_chk.c b/crypto/rsa/rsa_chk.c
index 9d848db..cc30e77 100644
--- a/crypto/rsa/rsa_chk.c
+++ b/crypto/rsa/rsa_chk.c
@@ -59,6 +59,12 @@
 	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/crypto/rsa/rsa_pmeth.c b/crypto/rsa/rsa_pmeth.c
index 5b2ecf5..157aa5c 100644
--- a/crypto/rsa/rsa_pmeth.c
+++ b/crypto/rsa/rsa_pmeth.c
@@ -611,6 +611,8 @@
 			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/crypto/sha/asm/sha1-parisc.pl b/crypto/sha/asm/sha1-parisc.pl
index 6d7bf49..6e5a328 100644
--- a/crypto/sha/asm/sha1-parisc.pl
+++ b/crypto/sha/asm/sha1-parisc.pl
@@ -254,6 +254,7 @@
 ___
 
 $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/crypto/sha/asm/sha1-x86_64.pl b/crypto/sha/asm/sha1-x86_64.pl
index cfdc45c..f15c7ec 100755
--- a/crypto/sha/asm/sha1-x86_64.pl
+++ b/crypto/sha/asm/sha1-x86_64.pl
@@ -745,7 +745,7 @@
 	mov	%rdi,$ctx	# reassigned argument
 	mov	%rsi,$inp	# reassigned argument
 	mov	%rdx,$num	# reassigned argument
-	vzeroall
+	vzeroupper
 
 	shl	\$6,$num
 	add	$inp,$num
@@ -1038,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/crypto/sha/asm/sha256-mips.S b/crypto/sha/asm/sha256-mips.S
index 5fc697f..2bd728e 100644
--- a/crypto/sha/asm/sha256-mips.S
+++ b/crypto/sha/asm/sha256-mips.S
@@ -1957,7 +1957,7 @@
 	sw	$30,6*4($4)
 	sw	$31,7*4($4)
 
-	bnel	$5,$23,.Loop
+	bne	$5,$23,.Loop
 	sub $6,192	# rewind $6
 
 	lw	$31,128-1*4($29)
diff --git a/crypto/sha/asm/sha512-mips.pl b/crypto/sha/asm/sha512-mips.pl
index ba5b250..ffa053b 100644
--- a/crypto/sha/asm/sha512-mips.pl
+++ b/crypto/sha/asm/sha512-mips.pl
@@ -351,7 +351,7 @@
 	$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/crypto/sha/asm/sha512-parisc.pl b/crypto/sha/asm/sha512-parisc.pl
index e24ee58..fc0e15b 100755
--- a/crypto/sha/asm/sha512-parisc.pl
+++ b/crypto/sha/asm/sha512-parisc.pl
@@ -785,6 +785,8 @@
 
 	s/cmpb,\*/comb,/ if ($SIZE_T==4);
 
+	s/\bbv\b/bve/    if ($SIZE_T==8);
+
 	print $_,"\n";
 }
 
diff --git a/crypto/sha/sha512.c b/crypto/sha/sha512.c
index 50dd7dc..50c229d 100644
--- a/crypto/sha/sha512.c
+++ b/crypto/sha/sha512.c
@@ -232,7 +232,14 @@
 {   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/crypto/srp/srp_grps.h b/crypto/srp/srp_grps.h
index d77c9ff..8e3c35e 100644
--- a/crypto/srp/srp_grps.h
+++ b/crypto/srp/srp_grps.h
@@ -1,22 +1,22 @@
 /* start of generated data */
 
 static BN_ULONG bn_group_1024_value[] = {
-	bn_pack4(9FC6,1D2F,C0EB,06E3),
-	bn_pack4(FD51,38FE,8376,435B),
-	bn_pack4(2FD4,CBF4,976E,AA9A),
-	bn_pack4(68ED,BC3C,0572,6CC0),
-	bn_pack4(C529,F566,660E,57EC),
-	bn_pack4(8255,9B29,7BCF,1885),
-	bn_pack4(CE8E,F4AD,69B1,5D49),
-	bn_pack4(5DC7,D7B4,6154,D6B6),
-	bn_pack4(8E49,5C1D,6089,DAD1),
-	bn_pack4(E0D5,D8E2,50B9,8BE4),
-	bn_pack4(383B,4813,D692,C6E0),
-	bn_pack4(D674,DF74,96EA,81D3),
-	bn_pack4(9EA2,314C,9C25,6576),
-	bn_pack4(6072,6187,75FF,3C0B),
-	bn_pack4(9C33,F80A,FA8F,C5E8),
-	bn_pack4(EEAF,0AB9,ADB3,8DD6)
+	bn_pack4(0x9FC6,0x1D2F,0xC0EB,0x06E3),
+	bn_pack4(0xFD51,0x38FE,0x8376,0x435B),
+	bn_pack4(0x2FD4,0xCBF4,0x976E,0xAA9A),
+	bn_pack4(0x68ED,0xBC3C,0x0572,0x6CC0),
+	bn_pack4(0xC529,0xF566,0x660E,0x57EC),
+	bn_pack4(0x8255,0x9B29,0x7BCF,0x1885),
+	bn_pack4(0xCE8E,0xF4AD,0x69B1,0x5D49),
+	bn_pack4(0x5DC7,0xD7B4,0x6154,0xD6B6),
+	bn_pack4(0x8E49,0x5C1D,0x6089,0xDAD1),
+	bn_pack4(0xE0D5,0xD8E2,0x50B9,0x8BE4),
+	bn_pack4(0x383B,0x4813,0xD692,0xC6E0),
+	bn_pack4(0xD674,0xDF74,0x96EA,0x81D3),
+	bn_pack4(0x9EA2,0x314C,0x9C25,0x6576),
+	bn_pack4(0x6072,0x6187,0x75FF,0x3C0B),
+	bn_pack4(0x9C33,0xF80A,0xFA8F,0xC5E8),
+	bn_pack4(0xEEAF,0x0AB9,0xADB3,0x8DD6)
 };
 static BIGNUM bn_group_1024 = {
 	bn_group_1024_value,
@@ -27,30 +27,30 @@
 };
 
 static BN_ULONG bn_group_1536_value[] = {
-	bn_pack4(CF76,E3FE,D135,F9BB),
-	bn_pack4(1518,0F93,499A,234D),
-	bn_pack4(8CE7,A28C,2442,C6F3),
-	bn_pack4(5A02,1FFF,5E91,479E),
-	bn_pack4(7F8A,2FE9,B8B5,292E),
-	bn_pack4(837C,264A,E3A9,BEB8),
-	bn_pack4(E442,734A,F7CC,B7AE),
-	bn_pack4(6577,2E43,7D6C,7F8C),
-	bn_pack4(DB2F,D53D,24B7,C486),
-	bn_pack4(6EDF,0195,3934,9627),
-	bn_pack4(158B,FD3E,2B9C,8CF5),
-	bn_pack4(764E,3F4B,53DD,9DA1),
-	bn_pack4(4754,8381,DBC5,B1FC),
-	bn_pack4(9B60,9E0B,E3BA,B63D),
-	bn_pack4(8134,B1C8,B979,8914),
-	bn_pack4(DF02,8A7C,EC67,F0D0),
-	bn_pack4(80B6,55BB,9A22,E8DC),
-	bn_pack4(1558,903B,A0D0,F843),
-	bn_pack4(51C6,A94B,E460,7A29),
-	bn_pack4(5F4F,5F55,6E27,CBDE),
-	bn_pack4(BEEE,A961,4B19,CC4D),
-	bn_pack4(DBA5,1DF4,99AC,4C80),
-	bn_pack4(B1F1,2A86,17A4,7BBB),
-	bn_pack4(9DEF,3CAF,B939,277A)
+	bn_pack4(0xCF76,0xE3FE,0xD135,0xF9BB),
+	bn_pack4(0x1518,0x0F93,0x499A,0x234D),
+	bn_pack4(0x8CE7,0xA28C,0x2442,0xC6F3),
+	bn_pack4(0x5A02,0x1FFF,0x5E91,0x479E),
+	bn_pack4(0x7F8A,0x2FE9,0xB8B5,0x292E),
+	bn_pack4(0x837C,0x264A,0xE3A9,0xBEB8),
+	bn_pack4(0xE442,0x734A,0xF7CC,0xB7AE),
+	bn_pack4(0x6577,0x2E43,0x7D6C,0x7F8C),
+	bn_pack4(0xDB2F,0xD53D,0x24B7,0xC486),
+	bn_pack4(0x6EDF,0x0195,0x3934,0x9627),
+	bn_pack4(0x158B,0xFD3E,0x2B9C,0x8CF5),
+	bn_pack4(0x764E,0x3F4B,0x53DD,0x9DA1),
+	bn_pack4(0x4754,0x8381,0xDBC5,0xB1FC),
+	bn_pack4(0x9B60,0x9E0B,0xE3BA,0xB63D),
+	bn_pack4(0x8134,0xB1C8,0xB979,0x8914),
+	bn_pack4(0xDF02,0x8A7C,0xEC67,0xF0D0),
+	bn_pack4(0x80B6,0x55BB,0x9A22,0xE8DC),
+	bn_pack4(0x1558,0x903B,0xA0D0,0xF843),
+	bn_pack4(0x51C6,0xA94B,0xE460,0x7A29),
+	bn_pack4(0x5F4F,0x5F55,0x6E27,0xCBDE),
+	bn_pack4(0xBEEE,0xA961,0x4B19,0xCC4D),
+	bn_pack4(0xDBA5,0x1DF4,0x99AC,0x4C80),
+	bn_pack4(0xB1F1,0x2A86,0x17A4,0x7BBB),
+	bn_pack4(0x9DEF,0x3CAF,0xB939,0x277A)
 };
 static BIGNUM bn_group_1536 = {
 	bn_group_1536_value,
@@ -61,38 +61,38 @@
 };
 
 static BN_ULONG bn_group_2048_value[] = {
-	bn_pack4(0FA7,111F,9E4A,FF73),
-	bn_pack4(9B65,E372,FCD6,8EF2),
-	bn_pack4(35DE,236D,525F,5475),
-	bn_pack4(94B5,C803,D89F,7AE4),
-	bn_pack4(71AE,35F8,E9DB,FBB6),
-	bn_pack4(2A56,98F3,A8D0,C382),
-	bn_pack4(9CCC,041C,7BC3,08D8),
-	bn_pack4(AF87,4E73,03CE,5329),
-	bn_pack4(6160,2790,04E5,7AE6),
-	bn_pack4(032C,FBDB,F52F,B378),
-	bn_pack4(5EA7,7A27,75D2,ECFA),
-	bn_pack4(5445,23B5,24B0,D57D),
-	bn_pack4(5B9D,32E6,88F8,7748),
-	bn_pack4(F1D2,B907,8717,461A),
-	bn_pack4(76BD,207A,436C,6481),
-	bn_pack4(CA97,B43A,23FB,8016),
-	bn_pack4(1D28,1E44,6B14,773B),
-	bn_pack4(7359,D041,D5C3,3EA7),
-	bn_pack4(A80D,740A,DBF4,FF74),
-	bn_pack4(55F9,7993,EC97,5EEA),
-	bn_pack4(2918,A996,2F0B,93B8),
-	bn_pack4(661A,05FB,D5FA,AAE8),
-	bn_pack4(CF60,9517,9A16,3AB3),
-	bn_pack4(E808,3969,EDB7,67B0),
-	bn_pack4(CD7F,48A9,DA04,FD50),
-	bn_pack4(D523,12AB,4B03,310D),
-	bn_pack4(8193,E075,7767,A13D),
-	bn_pack4(A373,29CB,B4A0,99ED),
-	bn_pack4(FC31,9294,3DB5,6050),
-	bn_pack4(AF72,B665,1987,EE07),
-	bn_pack4(F166,DE5E,1389,582F),
-	bn_pack4(AC6B,DB41,324A,9A9B)
+	bn_pack4(0x0FA7,0x111F,0x9E4A,0xFF73),
+	bn_pack4(0x9B65,0xE372,0xFCD6,0x8EF2),
+	bn_pack4(0x35DE,0x236D,0x525F,0x5475),
+	bn_pack4(0x94B5,0xC803,0xD89F,0x7AE4),
+	bn_pack4(0x71AE,0x35F8,0xE9DB,0xFBB6),
+	bn_pack4(0x2A56,0x98F3,0xA8D0,0xC382),
+	bn_pack4(0x9CCC,0x041C,0x7BC3,0x08D8),
+	bn_pack4(0xAF87,0x4E73,0x03CE,0x5329),
+	bn_pack4(0x6160,0x2790,0x04E5,0x7AE6),
+	bn_pack4(0x032C,0xFBDB,0xF52F,0xB378),
+	bn_pack4(0x5EA7,0x7A27,0x75D2,0xECFA),
+	bn_pack4(0x5445,0x23B5,0x24B0,0xD57D),
+	bn_pack4(0x5B9D,0x32E6,0x88F8,0x7748),
+	bn_pack4(0xF1D2,0xB907,0x8717,0x461A),
+	bn_pack4(0x76BD,0x207A,0x436C,0x6481),
+	bn_pack4(0xCA97,0xB43A,0x23FB,0x8016),
+	bn_pack4(0x1D28,0x1E44,0x6B14,0x773B),
+	bn_pack4(0x7359,0xD041,0xD5C3,0x3EA7),
+	bn_pack4(0xA80D,0x740A,0xDBF4,0xFF74),
+	bn_pack4(0x55F9,0x7993,0xEC97,0x5EEA),
+	bn_pack4(0x2918,0xA996,0x2F0B,0x93B8),
+	bn_pack4(0x661A,0x05FB,0xD5FA,0xAAE8),
+	bn_pack4(0xCF60,0x9517,0x9A16,0x3AB3),
+	bn_pack4(0xE808,0x3969,0xEDB7,0x67B0),
+	bn_pack4(0xCD7F,0x48A9,0xDA04,0xFD50),
+	bn_pack4(0xD523,0x12AB,0x4B03,0x310D),
+	bn_pack4(0x8193,0xE075,0x7767,0xA13D),
+	bn_pack4(0xA373,0x29CB,0xB4A0,0x99ED),
+	bn_pack4(0xFC31,0x9294,0x3DB5,0x6050),
+	bn_pack4(0xAF72,0xB665,0x1987,0xEE07),
+	bn_pack4(0xF166,0xDE5E,0x1389,0x582F),
+	bn_pack4(0xAC6B,0xDB41,0x324A,0x9A9B)
 };
 static BIGNUM bn_group_2048 = {
 	bn_group_2048_value,
@@ -103,54 +103,54 @@
 };
 
 static BN_ULONG bn_group_3072_value[] = {
-	bn_pack4(FFFF,FFFF,FFFF,FFFF),
-	bn_pack4(4B82,D120,A93A,D2CA),
-	bn_pack4(43DB,5BFC,E0FD,108E),
-	bn_pack4(08E2,4FA0,74E5,AB31),
-	bn_pack4(7709,88C0,BAD9,46E2),
-	bn_pack4(BBE1,1757,7A61,5D6C),
-	bn_pack4(521F,2B18,177B,200C),
-	bn_pack4(D876,0273,3EC8,6A64),
-	bn_pack4(F12F,FA06,D98A,0864),
-	bn_pack4(CEE3,D226,1AD2,EE6B),
-	bn_pack4(1E8C,94E0,4A25,619D),
-	bn_pack4(ABF5,AE8C,DB09,33D7),
-	bn_pack4(B397,0F85,A6E1,E4C7),
-	bn_pack4(8AEA,7157,5D06,0C7D),
-	bn_pack4(ECFB,8504,58DB,EF0A),
-	bn_pack4(A855,21AB,DF1C,BA64),
-	bn_pack4(AD33,170D,0450,7A33),
-	bn_pack4(1572,8E5A,8AAA,C42D),
-	bn_pack4(15D2,2618,98FA,0510),
-	bn_pack4(3995,497C,EA95,6AE5),
-	bn_pack4(DE2B,CBF6,9558,1718),
-	bn_pack4(B5C5,5DF0,6F4C,52C9),
-	bn_pack4(9B27,83A2,EC07,A28F),
-	bn_pack4(E39E,772C,180E,8603),
-	bn_pack4(3290,5E46,2E36,CE3B),
-	bn_pack4(F174,6C08,CA18,217C),
-	bn_pack4(670C,354E,4ABC,9804),
-	bn_pack4(9ED5,2907,7096,966D),
-	bn_pack4(1C62,F356,2085,52BB),
-	bn_pack4(8365,5D23,DCA3,AD96),
-	bn_pack4(6916,3FA8,FD24,CF5F),
-	bn_pack4(98DA,4836,1C55,D39A),
-	bn_pack4(C200,7CB8,A163,BF05),
-	bn_pack4(4928,6651,ECE4,5B3D),
-	bn_pack4(AE9F,2411,7C4B,1FE6),
-	bn_pack4(EE38,6BFB,5A89,9FA5),
-	bn_pack4(0BFF,5CB6,F406,B7ED),
-	bn_pack4(F44C,42E9,A637,ED6B),
-	bn_pack4(E485,B576,625E,7EC6),
-	bn_pack4(4FE1,356D,6D51,C245),
-	bn_pack4(302B,0A6D,F25F,1437),
-	bn_pack4(EF95,19B3,CD3A,431B),
-	bn_pack4(514A,0879,8E34,04DD),
-	bn_pack4(020B,BEA6,3B13,9B22),
-	bn_pack4(2902,4E08,8A67,CC74),
-	bn_pack4(C4C6,628B,80DC,1CD1),
-	bn_pack4(C90F,DAA2,2168,C234),
-	bn_pack4(FFFF,FFFF,FFFF,FFFF)
+	bn_pack4(0xFFFF,0xFFFF,0xFFFF,0xFFFF),
+	bn_pack4(0x4B82,0xD120,0xA93A,0xD2CA),
+	bn_pack4(0x43DB,0x5BFC,0xE0FD,0x108E),
+	bn_pack4(0x08E2,0x4FA0,0x74E5,0xAB31),
+	bn_pack4(0x7709,0x88C0,0xBAD9,0x46E2),
+	bn_pack4(0xBBE1,0x1757,0x7A61,0x5D6C),
+	bn_pack4(0x521F,0x2B18,0x177B,0x200C),
+	bn_pack4(0xD876,0x0273,0x3EC8,0x6A64),
+	bn_pack4(0xF12F,0xFA06,0xD98A,0x0864),
+	bn_pack4(0xCEE3,0xD226,0x1AD2,0xEE6B),
+	bn_pack4(0x1E8C,0x94E0,0x4A25,0x619D),
+	bn_pack4(0xABF5,0xAE8C,0xDB09,0x33D7),
+	bn_pack4(0xB397,0x0F85,0xA6E1,0xE4C7),
+	bn_pack4(0x8AEA,0x7157,0x5D06,0x0C7D),
+	bn_pack4(0xECFB,0x8504,0x58DB,0xEF0A),
+	bn_pack4(0xA855,0x21AB,0xDF1C,0xBA64),
+	bn_pack4(0xAD33,0x170D,0x0450,0x7A33),
+	bn_pack4(0x1572,0x8E5A,0x8AAA,0xC42D),
+	bn_pack4(0x15D2,0x2618,0x98FA,0x0510),
+	bn_pack4(0x3995,0x497C,0xEA95,0x6AE5),
+	bn_pack4(0xDE2B,0xCBF6,0x9558,0x1718),
+	bn_pack4(0xB5C5,0x5DF0,0x6F4C,0x52C9),
+	bn_pack4(0x9B27,0x83A2,0xEC07,0xA28F),
+	bn_pack4(0xE39E,0x772C,0x180E,0x8603),
+	bn_pack4(0x3290,0x5E46,0x2E36,0xCE3B),
+	bn_pack4(0xF174,0x6C08,0xCA18,0x217C),
+	bn_pack4(0x670C,0x354E,0x4ABC,0x9804),
+	bn_pack4(0x9ED5,0x2907,0x7096,0x966D),
+	bn_pack4(0x1C62,0xF356,0x2085,0x52BB),
+	bn_pack4(0x8365,0x5D23,0xDCA3,0xAD96),
+	bn_pack4(0x6916,0x3FA8,0xFD24,0xCF5F),
+	bn_pack4(0x98DA,0x4836,0x1C55,0xD39A),
+	bn_pack4(0xC200,0x7CB8,0xA163,0xBF05),
+	bn_pack4(0x4928,0x6651,0xECE4,0x5B3D),
+	bn_pack4(0xAE9F,0x2411,0x7C4B,0x1FE6),
+	bn_pack4(0xEE38,0x6BFB,0x5A89,0x9FA5),
+	bn_pack4(0x0BFF,0x5CB6,0xF406,0xB7ED),
+	bn_pack4(0xF44C,0x42E9,0xA637,0xED6B),
+	bn_pack4(0xE485,0xB576,0x625E,0x7EC6),
+	bn_pack4(0x4FE1,0x356D,0x6D51,0xC245),
+	bn_pack4(0x302B,0x0A6D,0xF25F,0x1437),
+	bn_pack4(0xEF95,0x19B3,0xCD3A,0x431B),
+	bn_pack4(0x514A,0x0879,0x8E34,0x04DD),
+	bn_pack4(0x020B,0xBEA6,0x3B13,0x9B22),
+	bn_pack4(0x2902,0x4E08,0x8A67,0xCC74),
+	bn_pack4(0xC4C6,0x628B,0x80DC,0x1CD1),
+	bn_pack4(0xC90F,0xDAA2,0x2168,0xC234),
+	bn_pack4(0xFFFF,0xFFFF,0xFFFF,0xFFFF)
 };
 static BIGNUM bn_group_3072 = {
 	bn_group_3072_value,
@@ -161,70 +161,70 @@
 };
 
 static BN_ULONG bn_group_4096_value[] = {
-	bn_pack4(FFFF,FFFF,FFFF,FFFF),
-	bn_pack4(4DF4,35C9,3406,3199),
-	bn_pack4(86FF,B7DC,90A6,C08F),
-	bn_pack4(93B4,EA98,8D8F,DDC1),
-	bn_pack4(D006,9127,D5B0,5AA9),
-	bn_pack4(B81B,DD76,2170,481C),
-	bn_pack4(1F61,2970,CEE2,D7AF),
-	bn_pack4(233B,A186,515B,E7ED),
-	bn_pack4(99B2,964F,A090,C3A2),
-	bn_pack4(287C,5947,4E6B,C05D),
-	bn_pack4(2E8E,FC14,1FBE,CAA6),
-	bn_pack4(DBBB,C2DB,04DE,8EF9),
-	bn_pack4(2583,E9CA,2AD4,4CE8),
-	bn_pack4(1A94,6834,B615,0BDA),
-	bn_pack4(99C3,2718,6AF4,E23C),
-	bn_pack4(8871,9A10,BDBA,5B26),
-	bn_pack4(1A72,3C12,A787,E6D7),
-	bn_pack4(4B82,D120,A921,0801),
-	bn_pack4(43DB,5BFC,E0FD,108E),
-	bn_pack4(08E2,4FA0,74E5,AB31),
-	bn_pack4(7709,88C0,BAD9,46E2),
-	bn_pack4(BBE1,1757,7A61,5D6C),
-	bn_pack4(521F,2B18,177B,200C),
-	bn_pack4(D876,0273,3EC8,6A64),
-	bn_pack4(F12F,FA06,D98A,0864),
-	bn_pack4(CEE3,D226,1AD2,EE6B),
-	bn_pack4(1E8C,94E0,4A25,619D),
-	bn_pack4(ABF5,AE8C,DB09,33D7),
-	bn_pack4(B397,0F85,A6E1,E4C7),
-	bn_pack4(8AEA,7157,5D06,0C7D),
-	bn_pack4(ECFB,8504,58DB,EF0A),
-	bn_pack4(A855,21AB,DF1C,BA64),
-	bn_pack4(AD33,170D,0450,7A33),
-	bn_pack4(1572,8E5A,8AAA,C42D),
-	bn_pack4(15D2,2618,98FA,0510),
-	bn_pack4(3995,497C,EA95,6AE5),
-	bn_pack4(DE2B,CBF6,9558,1718),
-	bn_pack4(B5C5,5DF0,6F4C,52C9),
-	bn_pack4(9B27,83A2,EC07,A28F),
-	bn_pack4(E39E,772C,180E,8603),
-	bn_pack4(3290,5E46,2E36,CE3B),
-	bn_pack4(F174,6C08,CA18,217C),
-	bn_pack4(670C,354E,4ABC,9804),
-	bn_pack4(9ED5,2907,7096,966D),
-	bn_pack4(1C62,F356,2085,52BB),
-	bn_pack4(8365,5D23,DCA3,AD96),
-	bn_pack4(6916,3FA8,FD24,CF5F),
-	bn_pack4(98DA,4836,1C55,D39A),
-	bn_pack4(C200,7CB8,A163,BF05),
-	bn_pack4(4928,6651,ECE4,5B3D),
-	bn_pack4(AE9F,2411,7C4B,1FE6),
-	bn_pack4(EE38,6BFB,5A89,9FA5),
-	bn_pack4(0BFF,5CB6,F406,B7ED),
-	bn_pack4(F44C,42E9,A637,ED6B),
-	bn_pack4(E485,B576,625E,7EC6),
-	bn_pack4(4FE1,356D,6D51,C245),
-	bn_pack4(302B,0A6D,F25F,1437),
-	bn_pack4(EF95,19B3,CD3A,431B),
-	bn_pack4(514A,0879,8E34,04DD),
-	bn_pack4(020B,BEA6,3B13,9B22),
-	bn_pack4(2902,4E08,8A67,CC74),
-	bn_pack4(C4C6,628B,80DC,1CD1),
-	bn_pack4(C90F,DAA2,2168,C234),
-	bn_pack4(FFFF,FFFF,FFFF,FFFF)
+	bn_pack4(0xFFFF,0xFFFF,0xFFFF,0xFFFF),
+	bn_pack4(0x4DF4,0x35C9,0x3406,0x3199),
+	bn_pack4(0x86FF,0xB7DC,0x90A6,0xC08F),
+	bn_pack4(0x93B4,0xEA98,0x8D8F,0xDDC1),
+	bn_pack4(0xD006,0x9127,0xD5B0,0x5AA9),
+	bn_pack4(0xB81B,0xDD76,0x2170,0x481C),
+	bn_pack4(0x1F61,0x2970,0xCEE2,0xD7AF),
+	bn_pack4(0x233B,0xA186,0x515B,0xE7ED),
+	bn_pack4(0x99B2,0x964F,0xA090,0xC3A2),
+	bn_pack4(0x287C,0x5947,0x4E6B,0xC05D),
+	bn_pack4(0x2E8E,0xFC14,0x1FBE,0xCAA6),
+	bn_pack4(0xDBBB,0xC2DB,0x04DE,0x8EF9),
+	bn_pack4(0x2583,0xE9CA,0x2AD4,0x4CE8),
+	bn_pack4(0x1A94,0x6834,0xB615,0x0BDA),
+	bn_pack4(0x99C3,0x2718,0x6AF4,0xE23C),
+	bn_pack4(0x8871,0x9A10,0xBDBA,0x5B26),
+	bn_pack4(0x1A72,0x3C12,0xA787,0xE6D7),
+	bn_pack4(0x4B82,0xD120,0xA921,0x0801),
+	bn_pack4(0x43DB,0x5BFC,0xE0FD,0x108E),
+	bn_pack4(0x08E2,0x4FA0,0x74E5,0xAB31),
+	bn_pack4(0x7709,0x88C0,0xBAD9,0x46E2),
+	bn_pack4(0xBBE1,0x1757,0x7A61,0x5D6C),
+	bn_pack4(0x521F,0x2B18,0x177B,0x200C),
+	bn_pack4(0xD876,0x0273,0x3EC8,0x6A64),
+	bn_pack4(0xF12F,0xFA06,0xD98A,0x0864),
+	bn_pack4(0xCEE3,0xD226,0x1AD2,0xEE6B),
+	bn_pack4(0x1E8C,0x94E0,0x4A25,0x619D),
+	bn_pack4(0xABF5,0xAE8C,0xDB09,0x33D7),
+	bn_pack4(0xB397,0x0F85,0xA6E1,0xE4C7),
+	bn_pack4(0x8AEA,0x7157,0x5D06,0x0C7D),
+	bn_pack4(0xECFB,0x8504,0x58DB,0xEF0A),
+	bn_pack4(0xA855,0x21AB,0xDF1C,0xBA64),
+	bn_pack4(0xAD33,0x170D,0x0450,0x7A33),
+	bn_pack4(0x1572,0x8E5A,0x8AAA,0xC42D),
+	bn_pack4(0x15D2,0x2618,0x98FA,0x0510),
+	bn_pack4(0x3995,0x497C,0xEA95,0x6AE5),
+	bn_pack4(0xDE2B,0xCBF6,0x9558,0x1718),
+	bn_pack4(0xB5C5,0x5DF0,0x6F4C,0x52C9),
+	bn_pack4(0x9B27,0x83A2,0xEC07,0xA28F),
+	bn_pack4(0xE39E,0x772C,0x180E,0x8603),
+	bn_pack4(0x3290,0x5E46,0x2E36,0xCE3B),
+	bn_pack4(0xF174,0x6C08,0xCA18,0x217C),
+	bn_pack4(0x670C,0x354E,0x4ABC,0x9804),
+	bn_pack4(0x9ED5,0x2907,0x7096,0x966D),
+	bn_pack4(0x1C62,0xF356,0x2085,0x52BB),
+	bn_pack4(0x8365,0x5D23,0xDCA3,0xAD96),
+	bn_pack4(0x6916,0x3FA8,0xFD24,0xCF5F),
+	bn_pack4(0x98DA,0x4836,0x1C55,0xD39A),
+	bn_pack4(0xC200,0x7CB8,0xA163,0xBF05),
+	bn_pack4(0x4928,0x6651,0xECE4,0x5B3D),
+	bn_pack4(0xAE9F,0x2411,0x7C4B,0x1FE6),
+	bn_pack4(0xEE38,0x6BFB,0x5A89,0x9FA5),
+	bn_pack4(0x0BFF,0x5CB6,0xF406,0xB7ED),
+	bn_pack4(0xF44C,0x42E9,0xA637,0xED6B),
+	bn_pack4(0xE485,0xB576,0x625E,0x7EC6),
+	bn_pack4(0x4FE1,0x356D,0x6D51,0xC245),
+	bn_pack4(0x302B,0x0A6D,0xF25F,0x1437),
+	bn_pack4(0xEF95,0x19B3,0xCD3A,0x431B),
+	bn_pack4(0x514A,0x0879,0x8E34,0x04DD),
+	bn_pack4(0x020B,0xBEA6,0x3B13,0x9B22),
+	bn_pack4(0x2902,0x4E08,0x8A67,0xCC74),
+	bn_pack4(0xC4C6,0x628B,0x80DC,0x1CD1),
+	bn_pack4(0xC90F,0xDAA2,0x2168,0xC234),
+	bn_pack4(0xFFFF,0xFFFF,0xFFFF,0xFFFF)
 };
 static BIGNUM bn_group_4096 = {
 	bn_group_4096_value,
@@ -235,102 +235,102 @@
 };
 
 static BN_ULONG bn_group_6144_value[] = {
-	bn_pack4(FFFF,FFFF,FFFF,FFFF),
-	bn_pack4(E694,F91E,6DCC,4024),
-	bn_pack4(12BF,2D5B,0B74,74D6),
-	bn_pack4(043E,8F66,3F48,60EE),
-	bn_pack4(387F,E8D7,6E3C,0468),
-	bn_pack4(DA56,C9EC,2EF2,9632),
-	bn_pack4(EB19,CCB1,A313,D55C),
-	bn_pack4(F550,AA3D,8A1F,BFF0),
-	bn_pack4(06A1,D58B,B7C5,DA76),
-	bn_pack4(A797,15EE,F29B,E328),
-	bn_pack4(14CC,5ED2,0F80,37E0),
-	bn_pack4(CC8F,6D7E,BF48,E1D8),
-	bn_pack4(4BD4,07B2,2B41,54AA),
-	bn_pack4(0F1D,45B7,FF58,5AC5),
-	bn_pack4(23A9,7A7E,36CC,88BE),
-	bn_pack4(59E7,C97F,BEC7,E8F3),
-	bn_pack4(B5A8,4031,900B,1C9E),
-	bn_pack4(D55E,702F,4698,0C82),
-	bn_pack4(F482,D7CE,6E74,FEF6),
-	bn_pack4(F032,EA15,D172,1D03),
-	bn_pack4(5983,CA01,C64B,92EC),
-	bn_pack4(6FB8,F401,378C,D2BF),
-	bn_pack4(3320,5151,2BD7,AF42),
-	bn_pack4(DB7F,1447,E6CC,254B),
-	bn_pack4(44CE,6CBA,CED4,BB1B),
-	bn_pack4(DA3E,DBEB,CF9B,14ED),
-	bn_pack4(1797,27B0,865A,8918),
-	bn_pack4(B06A,53ED,9027,D831),
-	bn_pack4(E5DB,382F,4130,01AE),
-	bn_pack4(F8FF,9406,AD9E,530E),
-	bn_pack4(C975,1E76,3DBA,37BD),
-	bn_pack4(C1D4,DCB2,6026,46DE),
-	bn_pack4(36C3,FAB4,D27C,7026),
-	bn_pack4(4DF4,35C9,3402,8492),
-	bn_pack4(86FF,B7DC,90A6,C08F),
-	bn_pack4(93B4,EA98,8D8F,DDC1),
-	bn_pack4(D006,9127,D5B0,5AA9),
-	bn_pack4(B81B,DD76,2170,481C),
-	bn_pack4(1F61,2970,CEE2,D7AF),
-	bn_pack4(233B,A186,515B,E7ED),
-	bn_pack4(99B2,964F,A090,C3A2),
-	bn_pack4(287C,5947,4E6B,C05D),
-	bn_pack4(2E8E,FC14,1FBE,CAA6),
-	bn_pack4(DBBB,C2DB,04DE,8EF9),
-	bn_pack4(2583,E9CA,2AD4,4CE8),
-	bn_pack4(1A94,6834,B615,0BDA),
-	bn_pack4(99C3,2718,6AF4,E23C),
-	bn_pack4(8871,9A10,BDBA,5B26),
-	bn_pack4(1A72,3C12,A787,E6D7),
-	bn_pack4(4B82,D120,A921,0801),
-	bn_pack4(43DB,5BFC,E0FD,108E),
-	bn_pack4(08E2,4FA0,74E5,AB31),
-	bn_pack4(7709,88C0,BAD9,46E2),
-	bn_pack4(BBE1,1757,7A61,5D6C),
-	bn_pack4(521F,2B18,177B,200C),
-	bn_pack4(D876,0273,3EC8,6A64),
-	bn_pack4(F12F,FA06,D98A,0864),
-	bn_pack4(CEE3,D226,1AD2,EE6B),
-	bn_pack4(1E8C,94E0,4A25,619D),
-	bn_pack4(ABF5,AE8C,DB09,33D7),
-	bn_pack4(B397,0F85,A6E1,E4C7),
-	bn_pack4(8AEA,7157,5D06,0C7D),
-	bn_pack4(ECFB,8504,58DB,EF0A),
-	bn_pack4(A855,21AB,DF1C,BA64),
-	bn_pack4(AD33,170D,0450,7A33),
-	bn_pack4(1572,8E5A,8AAA,C42D),
-	bn_pack4(15D2,2618,98FA,0510),
-	bn_pack4(3995,497C,EA95,6AE5),
-	bn_pack4(DE2B,CBF6,9558,1718),
-	bn_pack4(B5C5,5DF0,6F4C,52C9),
-	bn_pack4(9B27,83A2,EC07,A28F),
-	bn_pack4(E39E,772C,180E,8603),
-	bn_pack4(3290,5E46,2E36,CE3B),
-	bn_pack4(F174,6C08,CA18,217C),
-	bn_pack4(670C,354E,4ABC,9804),
-	bn_pack4(9ED5,2907,7096,966D),
-	bn_pack4(1C62,F356,2085,52BB),
-	bn_pack4(8365,5D23,DCA3,AD96),
-	bn_pack4(6916,3FA8,FD24,CF5F),
-	bn_pack4(98DA,4836,1C55,D39A),
-	bn_pack4(C200,7CB8,A163,BF05),
-	bn_pack4(4928,6651,ECE4,5B3D),
-	bn_pack4(AE9F,2411,7C4B,1FE6),
-	bn_pack4(EE38,6BFB,5A89,9FA5),
-	bn_pack4(0BFF,5CB6,F406,B7ED),
-	bn_pack4(F44C,42E9,A637,ED6B),
-	bn_pack4(E485,B576,625E,7EC6),
-	bn_pack4(4FE1,356D,6D51,C245),
-	bn_pack4(302B,0A6D,F25F,1437),
-	bn_pack4(EF95,19B3,CD3A,431B),
-	bn_pack4(514A,0879,8E34,04DD),
-	bn_pack4(020B,BEA6,3B13,9B22),
-	bn_pack4(2902,4E08,8A67,CC74),
-	bn_pack4(C4C6,628B,80DC,1CD1),
-	bn_pack4(C90F,DAA2,2168,C234),
-	bn_pack4(FFFF,FFFF,FFFF,FFFF)
+	bn_pack4(0xFFFF,0xFFFF,0xFFFF,0xFFFF),
+	bn_pack4(0xE694,0xF91E,0x6DCC,0x4024),
+	bn_pack4(0x12BF,0x2D5B,0x0B74,0x74D6),
+	bn_pack4(0x043E,0x8F66,0x3F48,0x60EE),
+	bn_pack4(0x387F,0xE8D7,0x6E3C,0x0468),
+	bn_pack4(0xDA56,0xC9EC,0x2EF2,0x9632),
+	bn_pack4(0xEB19,0xCCB1,0xA313,0xD55C),
+	bn_pack4(0xF550,0xAA3D,0x8A1F,0xBFF0),
+	bn_pack4(0x06A1,0xD58B,0xB7C5,0xDA76),
+	bn_pack4(0xA797,0x15EE,0xF29B,0xE328),
+	bn_pack4(0x14CC,0x5ED2,0x0F80,0x37E0),
+	bn_pack4(0xCC8F,0x6D7E,0xBF48,0xE1D8),
+	bn_pack4(0x4BD4,0x07B2,0x2B41,0x54AA),
+	bn_pack4(0x0F1D,0x45B7,0xFF58,0x5AC5),
+	bn_pack4(0x23A9,0x7A7E,0x36CC,0x88BE),
+	bn_pack4(0x59E7,0xC97F,0xBEC7,0xE8F3),
+	bn_pack4(0xB5A8,0x4031,0x900B,0x1C9E),
+	bn_pack4(0xD55E,0x702F,0x4698,0x0C82),
+	bn_pack4(0xF482,0xD7CE,0x6E74,0xFEF6),
+	bn_pack4(0xF032,0xEA15,0xD172,0x1D03),
+	bn_pack4(0x5983,0xCA01,0xC64B,0x92EC),
+	bn_pack4(0x6FB8,0xF401,0x378C,0xD2BF),
+	bn_pack4(0x3320,0x5151,0x2BD7,0xAF42),
+	bn_pack4(0xDB7F,0x1447,0xE6CC,0x254B),
+	bn_pack4(0x44CE,0x6CBA,0xCED4,0xBB1B),
+	bn_pack4(0xDA3E,0xDBEB,0xCF9B,0x14ED),
+	bn_pack4(0x1797,0x27B0,0x865A,0x8918),
+	bn_pack4(0xB06A,0x53ED,0x9027,0xD831),
+	bn_pack4(0xE5DB,0x382F,0x4130,0x01AE),
+	bn_pack4(0xF8FF,0x9406,0xAD9E,0x530E),
+	bn_pack4(0xC975,0x1E76,0x3DBA,0x37BD),
+	bn_pack4(0xC1D4,0xDCB2,0x6026,0x46DE),
+	bn_pack4(0x36C3,0xFAB4,0xD27C,0x7026),
+	bn_pack4(0x4DF4,0x35C9,0x3402,0x8492),
+	bn_pack4(0x86FF,0xB7DC,0x90A6,0xC08F),
+	bn_pack4(0x93B4,0xEA98,0x8D8F,0xDDC1),
+	bn_pack4(0xD006,0x9127,0xD5B0,0x5AA9),
+	bn_pack4(0xB81B,0xDD76,0x2170,0x481C),
+	bn_pack4(0x1F61,0x2970,0xCEE2,0xD7AF),
+	bn_pack4(0x233B,0xA186,0x515B,0xE7ED),
+	bn_pack4(0x99B2,0x964F,0xA090,0xC3A2),
+	bn_pack4(0x287C,0x5947,0x4E6B,0xC05D),
+	bn_pack4(0x2E8E,0xFC14,0x1FBE,0xCAA6),
+	bn_pack4(0xDBBB,0xC2DB,0x04DE,0x8EF9),
+	bn_pack4(0x2583,0xE9CA,0x2AD4,0x4CE8),
+	bn_pack4(0x1A94,0x6834,0xB615,0x0BDA),
+	bn_pack4(0x99C3,0x2718,0x6AF4,0xE23C),
+	bn_pack4(0x8871,0x9A10,0xBDBA,0x5B26),
+	bn_pack4(0x1A72,0x3C12,0xA787,0xE6D7),
+	bn_pack4(0x4B82,0xD120,0xA921,0x0801),
+	bn_pack4(0x43DB,0x5BFC,0xE0FD,0x108E),
+	bn_pack4(0x08E2,0x4FA0,0x74E5,0xAB31),
+	bn_pack4(0x7709,0x88C0,0xBAD9,0x46E2),
+	bn_pack4(0xBBE1,0x1757,0x7A61,0x5D6C),
+	bn_pack4(0x521F,0x2B18,0x177B,0x200C),
+	bn_pack4(0xD876,0x0273,0x3EC8,0x6A64),
+	bn_pack4(0xF12F,0xFA06,0xD98A,0x0864),
+	bn_pack4(0xCEE3,0xD226,0x1AD2,0xEE6B),
+	bn_pack4(0x1E8C,0x94E0,0x4A25,0x619D),
+	bn_pack4(0xABF5,0xAE8C,0xDB09,0x33D7),
+	bn_pack4(0xB397,0x0F85,0xA6E1,0xE4C7),
+	bn_pack4(0x8AEA,0x7157,0x5D06,0x0C7D),
+	bn_pack4(0xECFB,0x8504,0x58DB,0xEF0A),
+	bn_pack4(0xA855,0x21AB,0xDF1C,0xBA64),
+	bn_pack4(0xAD33,0x170D,0x0450,0x7A33),
+	bn_pack4(0x1572,0x8E5A,0x8AAA,0xC42D),
+	bn_pack4(0x15D2,0x2618,0x98FA,0x0510),
+	bn_pack4(0x3995,0x497C,0xEA95,0x6AE5),
+	bn_pack4(0xDE2B,0xCBF6,0x9558,0x1718),
+	bn_pack4(0xB5C5,0x5DF0,0x6F4C,0x52C9),
+	bn_pack4(0x9B27,0x83A2,0xEC07,0xA28F),
+	bn_pack4(0xE39E,0x772C,0x180E,0x8603),
+	bn_pack4(0x3290,0x5E46,0x2E36,0xCE3B),
+	bn_pack4(0xF174,0x6C08,0xCA18,0x217C),
+	bn_pack4(0x670C,0x354E,0x4ABC,0x9804),
+	bn_pack4(0x9ED5,0x2907,0x7096,0x966D),
+	bn_pack4(0x1C62,0xF356,0x2085,0x52BB),
+	bn_pack4(0x8365,0x5D23,0xDCA3,0xAD96),
+	bn_pack4(0x6916,0x3FA8,0xFD24,0xCF5F),
+	bn_pack4(0x98DA,0x4836,0x1C55,0xD39A),
+	bn_pack4(0xC200,0x7CB8,0xA163,0xBF05),
+	bn_pack4(0x4928,0x6651,0xECE4,0x5B3D),
+	bn_pack4(0xAE9F,0x2411,0x7C4B,0x1FE6),
+	bn_pack4(0xEE38,0x6BFB,0x5A89,0x9FA5),
+	bn_pack4(0x0BFF,0x5CB6,0xF406,0xB7ED),
+	bn_pack4(0xF44C,0x42E9,0xA637,0xED6B),
+	bn_pack4(0xE485,0xB576,0x625E,0x7EC6),
+	bn_pack4(0x4FE1,0x356D,0x6D51,0xC245),
+	bn_pack4(0x302B,0x0A6D,0xF25F,0x1437),
+	bn_pack4(0xEF95,0x19B3,0xCD3A,0x431B),
+	bn_pack4(0x514A,0x0879,0x8E34,0x04DD),
+	bn_pack4(0x020B,0xBEA6,0x3B13,0x9B22),
+	bn_pack4(0x2902,0x4E08,0x8A67,0xCC74),
+	bn_pack4(0xC4C6,0x628B,0x80DC,0x1CD1),
+	bn_pack4(0xC90F,0xDAA2,0x2168,0xC234),
+	bn_pack4(0xFFFF,0xFFFF,0xFFFF,0xFFFF)
 };
 static BIGNUM bn_group_6144 = {
 	bn_group_6144_value,
@@ -341,134 +341,134 @@
 };
 
 static BN_ULONG bn_group_8192_value[] = {
-	bn_pack4(FFFF,FFFF,FFFF,FFFF),
-	bn_pack4(60C9,80DD,98ED,D3DF),
-	bn_pack4(C81F,56E8,80B9,6E71),
-	bn_pack4(9E30,50E2,7656,94DF),
-	bn_pack4(9558,E447,5677,E9AA),
-	bn_pack4(C919,0DA6,FC02,6E47),
-	bn_pack4(889A,002E,D5EE,382B),
-	bn_pack4(4009,438B,481C,6CD7),
-	bn_pack4(3590,46F4,EB87,9F92),
-	bn_pack4(FAF3,6BC3,1ECF,A268),
-	bn_pack4(B1D5,10BD,7EE7,4D73),
-	bn_pack4(F9AB,4819,5DED,7EA1),
-	bn_pack4(64F3,1CC5,0846,851D),
-	bn_pack4(4597,E899,A025,5DC1),
-	bn_pack4(DF31,0EE0,74AB,6A36),
-	bn_pack4(6D2A,13F8,3F44,F82D),
-	bn_pack4(062B,3CF5,B3A2,78A6),
-	bn_pack4(7968,3303,ED5B,DD3A),
-	bn_pack4(FA9D,4B7F,A2C0,87E8),
-	bn_pack4(4BCB,C886,2F83,85DD),
-	bn_pack4(3473,FC64,6CEA,306B),
-	bn_pack4(13EB,57A8,1A23,F0C7),
-	bn_pack4(2222,2E04,A403,7C07),
-	bn_pack4(E3FD,B8BE,FC84,8AD9),
-	bn_pack4(238F,16CB,E39D,652D),
-	bn_pack4(3423,B474,2BF1,C978),
-	bn_pack4(3AAB,639C,5AE4,F568),
-	bn_pack4(2576,F693,6BA4,2466),
-	bn_pack4(741F,A7BF,8AFC,47ED),
-	bn_pack4(3BC8,32B6,8D9D,D300),
-	bn_pack4(D8BE,C4D0,73B9,31BA),
-	bn_pack4(3877,7CB6,A932,DF8C),
-	bn_pack4(74A3,926F,12FE,E5E4),
-	bn_pack4(E694,F91E,6DBE,1159),
-	bn_pack4(12BF,2D5B,0B74,74D6),
-	bn_pack4(043E,8F66,3F48,60EE),
-	bn_pack4(387F,E8D7,6E3C,0468),
-	bn_pack4(DA56,C9EC,2EF2,9632),
-	bn_pack4(EB19,CCB1,A313,D55C),
-	bn_pack4(F550,AA3D,8A1F,BFF0),
-	bn_pack4(06A1,D58B,B7C5,DA76),
-	bn_pack4(A797,15EE,F29B,E328),
-	bn_pack4(14CC,5ED2,0F80,37E0),
-	bn_pack4(CC8F,6D7E,BF48,E1D8),
-	bn_pack4(4BD4,07B2,2B41,54AA),
-	bn_pack4(0F1D,45B7,FF58,5AC5),
-	bn_pack4(23A9,7A7E,36CC,88BE),
-	bn_pack4(59E7,C97F,BEC7,E8F3),
-	bn_pack4(B5A8,4031,900B,1C9E),
-	bn_pack4(D55E,702F,4698,0C82),
-	bn_pack4(F482,D7CE,6E74,FEF6),
-	bn_pack4(F032,EA15,D172,1D03),
-	bn_pack4(5983,CA01,C64B,92EC),
-	bn_pack4(6FB8,F401,378C,D2BF),
-	bn_pack4(3320,5151,2BD7,AF42),
-	bn_pack4(DB7F,1447,E6CC,254B),
-	bn_pack4(44CE,6CBA,CED4,BB1B),
-	bn_pack4(DA3E,DBEB,CF9B,14ED),
-	bn_pack4(1797,27B0,865A,8918),
-	bn_pack4(B06A,53ED,9027,D831),
-	bn_pack4(E5DB,382F,4130,01AE),
-	bn_pack4(F8FF,9406,AD9E,530E),
-	bn_pack4(C975,1E76,3DBA,37BD),
-	bn_pack4(C1D4,DCB2,6026,46DE),
-	bn_pack4(36C3,FAB4,D27C,7026),
-	bn_pack4(4DF4,35C9,3402,8492),
-	bn_pack4(86FF,B7DC,90A6,C08F),
-	bn_pack4(93B4,EA98,8D8F,DDC1),
-	bn_pack4(D006,9127,D5B0,5AA9),
-	bn_pack4(B81B,DD76,2170,481C),
-	bn_pack4(1F61,2970,CEE2,D7AF),
-	bn_pack4(233B,A186,515B,E7ED),
-	bn_pack4(99B2,964F,A090,C3A2),
-	bn_pack4(287C,5947,4E6B,C05D),
-	bn_pack4(2E8E,FC14,1FBE,CAA6),
-	bn_pack4(DBBB,C2DB,04DE,8EF9),
-	bn_pack4(2583,E9CA,2AD4,4CE8),
-	bn_pack4(1A94,6834,B615,0BDA),
-	bn_pack4(99C3,2718,6AF4,E23C),
-	bn_pack4(8871,9A10,BDBA,5B26),
-	bn_pack4(1A72,3C12,A787,E6D7),
-	bn_pack4(4B82,D120,A921,0801),
-	bn_pack4(43DB,5BFC,E0FD,108E),
-	bn_pack4(08E2,4FA0,74E5,AB31),
-	bn_pack4(7709,88C0,BAD9,46E2),
-	bn_pack4(BBE1,1757,7A61,5D6C),
-	bn_pack4(521F,2B18,177B,200C),
-	bn_pack4(D876,0273,3EC8,6A64),
-	bn_pack4(F12F,FA06,D98A,0864),
-	bn_pack4(CEE3,D226,1AD2,EE6B),
-	bn_pack4(1E8C,94E0,4A25,619D),
-	bn_pack4(ABF5,AE8C,DB09,33D7),
-	bn_pack4(B397,0F85,A6E1,E4C7),
-	bn_pack4(8AEA,7157,5D06,0C7D),
-	bn_pack4(ECFB,8504,58DB,EF0A),
-	bn_pack4(A855,21AB,DF1C,BA64),
-	bn_pack4(AD33,170D,0450,7A33),
-	bn_pack4(1572,8E5A,8AAA,C42D),
-	bn_pack4(15D2,2618,98FA,0510),
-	bn_pack4(3995,497C,EA95,6AE5),
-	bn_pack4(DE2B,CBF6,9558,1718),
-	bn_pack4(B5C5,5DF0,6F4C,52C9),
-	bn_pack4(9B27,83A2,EC07,A28F),
-	bn_pack4(E39E,772C,180E,8603),
-	bn_pack4(3290,5E46,2E36,CE3B),
-	bn_pack4(F174,6C08,CA18,217C),
-	bn_pack4(670C,354E,4ABC,9804),
-	bn_pack4(9ED5,2907,7096,966D),
-	bn_pack4(1C62,F356,2085,52BB),
-	bn_pack4(8365,5D23,DCA3,AD96),
-	bn_pack4(6916,3FA8,FD24,CF5F),
-	bn_pack4(98DA,4836,1C55,D39A),
-	bn_pack4(C200,7CB8,A163,BF05),
-	bn_pack4(4928,6651,ECE4,5B3D),
-	bn_pack4(AE9F,2411,7C4B,1FE6),
-	bn_pack4(EE38,6BFB,5A89,9FA5),
-	bn_pack4(0BFF,5CB6,F406,B7ED),
-	bn_pack4(F44C,42E9,A637,ED6B),
-	bn_pack4(E485,B576,625E,7EC6),
-	bn_pack4(4FE1,356D,6D51,C245),
-	bn_pack4(302B,0A6D,F25F,1437),
-	bn_pack4(EF95,19B3,CD3A,431B),
-	bn_pack4(514A,0879,8E34,04DD),
-	bn_pack4(020B,BEA6,3B13,9B22),
-	bn_pack4(2902,4E08,8A67,CC74),
-	bn_pack4(C4C6,628B,80DC,1CD1),
-	bn_pack4(C90F,DAA2,2168,C234),
-	bn_pack4(FFFF,FFFF,FFFF,FFFF)
+	bn_pack4(0xFFFF,0xFFFF,0xFFFF,0xFFFF),
+	bn_pack4(0x60C9,0x80DD,0x98ED,0xD3DF),
+	bn_pack4(0xC81F,0x56E8,0x80B9,0x6E71),
+	bn_pack4(0x9E30,0x50E2,0x7656,0x94DF),
+	bn_pack4(0x9558,0xE447,0x5677,0xE9AA),
+	bn_pack4(0xC919,0x0DA6,0xFC02,0x6E47),
+	bn_pack4(0x889A,0x002E,0xD5EE,0x382B),
+	bn_pack4(0x4009,0x438B,0x481C,0x6CD7),
+	bn_pack4(0x3590,0x46F4,0xEB87,0x9F92),
+	bn_pack4(0xFAF3,0x6BC3,0x1ECF,0xA268),
+	bn_pack4(0xB1D5,0x10BD,0x7EE7,0x4D73),
+	bn_pack4(0xF9AB,0x4819,0x5DED,0x7EA1),
+	bn_pack4(0x64F3,0x1CC5,0x0846,0x851D),
+	bn_pack4(0x4597,0xE899,0xA025,0x5DC1),
+	bn_pack4(0xDF31,0x0EE0,0x74AB,0x6A36),
+	bn_pack4(0x6D2A,0x13F8,0x3F44,0xF82D),
+	bn_pack4(0x062B,0x3CF5,0xB3A2,0x78A6),
+	bn_pack4(0x7968,0x3303,0xED5B,0xDD3A),
+	bn_pack4(0xFA9D,0x4B7F,0xA2C0,0x87E8),
+	bn_pack4(0x4BCB,0xC886,0x2F83,0x85DD),
+	bn_pack4(0x3473,0xFC64,0x6CEA,0x306B),
+	bn_pack4(0x13EB,0x57A8,0x1A23,0xF0C7),
+	bn_pack4(0x2222,0x2E04,0xA403,0x7C07),
+	bn_pack4(0xE3FD,0xB8BE,0xFC84,0x8AD9),
+	bn_pack4(0x238F,0x16CB,0xE39D,0x652D),
+	bn_pack4(0x3423,0xB474,0x2BF1,0xC978),
+	bn_pack4(0x3AAB,0x639C,0x5AE4,0xF568),
+	bn_pack4(0x2576,0xF693,0x6BA4,0x2466),
+	bn_pack4(0x741F,0xA7BF,0x8AFC,0x47ED),
+	bn_pack4(0x3BC8,0x32B6,0x8D9D,0xD300),
+	bn_pack4(0xD8BE,0xC4D0,0x73B9,0x31BA),
+	bn_pack4(0x3877,0x7CB6,0xA932,0xDF8C),
+	bn_pack4(0x74A3,0x926F,0x12FE,0xE5E4),
+	bn_pack4(0xE694,0xF91E,0x6DBE,0x1159),
+	bn_pack4(0x12BF,0x2D5B,0x0B74,0x74D6),
+	bn_pack4(0x043E,0x8F66,0x3F48,0x60EE),
+	bn_pack4(0x387F,0xE8D7,0x6E3C,0x0468),
+	bn_pack4(0xDA56,0xC9EC,0x2EF2,0x9632),
+	bn_pack4(0xEB19,0xCCB1,0xA313,0xD55C),
+	bn_pack4(0xF550,0xAA3D,0x8A1F,0xBFF0),
+	bn_pack4(0x06A1,0xD58B,0xB7C5,0xDA76),
+	bn_pack4(0xA797,0x15EE,0xF29B,0xE328),
+	bn_pack4(0x14CC,0x5ED2,0x0F80,0x37E0),
+	bn_pack4(0xCC8F,0x6D7E,0xBF48,0xE1D8),
+	bn_pack4(0x4BD4,0x07B2,0x2B41,0x54AA),
+	bn_pack4(0x0F1D,0x45B7,0xFF58,0x5AC5),
+	bn_pack4(0x23A9,0x7A7E,0x36CC,0x88BE),
+	bn_pack4(0x59E7,0xC97F,0xBEC7,0xE8F3),
+	bn_pack4(0xB5A8,0x4031,0x900B,0x1C9E),
+	bn_pack4(0xD55E,0x702F,0x4698,0x0C82),
+	bn_pack4(0xF482,0xD7CE,0x6E74,0xFEF6),
+	bn_pack4(0xF032,0xEA15,0xD172,0x1D03),
+	bn_pack4(0x5983,0xCA01,0xC64B,0x92EC),
+	bn_pack4(0x6FB8,0xF401,0x378C,0xD2BF),
+	bn_pack4(0x3320,0x5151,0x2BD7,0xAF42),
+	bn_pack4(0xDB7F,0x1447,0xE6CC,0x254B),
+	bn_pack4(0x44CE,0x6CBA,0xCED4,0xBB1B),
+	bn_pack4(0xDA3E,0xDBEB,0xCF9B,0x14ED),
+	bn_pack4(0x1797,0x27B0,0x865A,0x8918),
+	bn_pack4(0xB06A,0x53ED,0x9027,0xD831),
+	bn_pack4(0xE5DB,0x382F,0x4130,0x01AE),
+	bn_pack4(0xF8FF,0x9406,0xAD9E,0x530E),
+	bn_pack4(0xC975,0x1E76,0x3DBA,0x37BD),
+	bn_pack4(0xC1D4,0xDCB2,0x6026,0x46DE),
+	bn_pack4(0x36C3,0xFAB4,0xD27C,0x7026),
+	bn_pack4(0x4DF4,0x35C9,0x3402,0x8492),
+	bn_pack4(0x86FF,0xB7DC,0x90A6,0xC08F),
+	bn_pack4(0x93B4,0xEA98,0x8D8F,0xDDC1),
+	bn_pack4(0xD006,0x9127,0xD5B0,0x5AA9),
+	bn_pack4(0xB81B,0xDD76,0x2170,0x481C),
+	bn_pack4(0x1F61,0x2970,0xCEE2,0xD7AF),
+	bn_pack4(0x233B,0xA186,0x515B,0xE7ED),
+	bn_pack4(0x99B2,0x964F,0xA090,0xC3A2),
+	bn_pack4(0x287C,0x5947,0x4E6B,0xC05D),
+	bn_pack4(0x2E8E,0xFC14,0x1FBE,0xCAA6),
+	bn_pack4(0xDBBB,0xC2DB,0x04DE,0x8EF9),
+	bn_pack4(0x2583,0xE9CA,0x2AD4,0x4CE8),
+	bn_pack4(0x1A94,0x6834,0xB615,0x0BDA),
+	bn_pack4(0x99C3,0x2718,0x6AF4,0xE23C),
+	bn_pack4(0x8871,0x9A10,0xBDBA,0x5B26),
+	bn_pack4(0x1A72,0x3C12,0xA787,0xE6D7),
+	bn_pack4(0x4B82,0xD120,0xA921,0x0801),
+	bn_pack4(0x43DB,0x5BFC,0xE0FD,0x108E),
+	bn_pack4(0x08E2,0x4FA0,0x74E5,0xAB31),
+	bn_pack4(0x7709,0x88C0,0xBAD9,0x46E2),
+	bn_pack4(0xBBE1,0x1757,0x7A61,0x5D6C),
+	bn_pack4(0x521F,0x2B18,0x177B,0x200C),
+	bn_pack4(0xD876,0x0273,0x3EC8,0x6A64),
+	bn_pack4(0xF12F,0xFA06,0xD98A,0x0864),
+	bn_pack4(0xCEE3,0xD226,0x1AD2,0xEE6B),
+	bn_pack4(0x1E8C,0x94E0,0x4A25,0x619D),
+	bn_pack4(0xABF5,0xAE8C,0xDB09,0x33D7),
+	bn_pack4(0xB397,0x0F85,0xA6E1,0xE4C7),
+	bn_pack4(0x8AEA,0x7157,0x5D06,0x0C7D),
+	bn_pack4(0xECFB,0x8504,0x58DB,0xEF0A),
+	bn_pack4(0xA855,0x21AB,0xDF1C,0xBA64),
+	bn_pack4(0xAD33,0x170D,0x0450,0x7A33),
+	bn_pack4(0x1572,0x8E5A,0x8AAA,0xC42D),
+	bn_pack4(0x15D2,0x2618,0x98FA,0x0510),
+	bn_pack4(0x3995,0x497C,0xEA95,0x6AE5),
+	bn_pack4(0xDE2B,0xCBF6,0x9558,0x1718),
+	bn_pack4(0xB5C5,0x5DF0,0x6F4C,0x52C9),
+	bn_pack4(0x9B27,0x83A2,0xEC07,0xA28F),
+	bn_pack4(0xE39E,0x772C,0x180E,0x8603),
+	bn_pack4(0x3290,0x5E46,0x2E36,0xCE3B),
+	bn_pack4(0xF174,0x6C08,0xCA18,0x217C),
+	bn_pack4(0x670C,0x354E,0x4ABC,0x9804),
+	bn_pack4(0x9ED5,0x2907,0x7096,0x966D),
+	bn_pack4(0x1C62,0xF356,0x2085,0x52BB),
+	bn_pack4(0x8365,0x5D23,0xDCA3,0xAD96),
+	bn_pack4(0x6916,0x3FA8,0xFD24,0xCF5F),
+	bn_pack4(0x98DA,0x4836,0x1C55,0xD39A),
+	bn_pack4(0xC200,0x7CB8,0xA163,0xBF05),
+	bn_pack4(0x4928,0x6651,0xECE4,0x5B3D),
+	bn_pack4(0xAE9F,0x2411,0x7C4B,0x1FE6),
+	bn_pack4(0xEE38,0x6BFB,0x5A89,0x9FA5),
+	bn_pack4(0x0BFF,0x5CB6,0xF406,0xB7ED),
+	bn_pack4(0xF44C,0x42E9,0xA637,0xED6B),
+	bn_pack4(0xE485,0xB576,0x625E,0x7EC6),
+	bn_pack4(0x4FE1,0x356D,0x6D51,0xC245),
+	bn_pack4(0x302B,0x0A6D,0xF25F,0x1437),
+	bn_pack4(0xEF95,0x19B3,0xCD3A,0x431B),
+	bn_pack4(0x514A,0x0879,0x8E34,0x04DD),
+	bn_pack4(0x020B,0xBEA6,0x3B13,0x9B22),
+	bn_pack4(0x2902,0x4E08,0x8A67,0xCC74),
+	bn_pack4(0xC4C6,0x628B,0x80DC,0x1CD1),
+	bn_pack4(0xC90F,0xDAA2,0x2168,0xC234),
+	bn_pack4(0xFFFF,0xFFFF,0xFFFF,0xFFFF)
 };
 static BIGNUM bn_group_8192 = {
 	bn_group_8192_value,
diff --git a/crypto/srp/srp_lib.c b/crypto/srp/srp_lib.c
index 92cea98..7c1dcc5 100644
--- a/crypto/srp/srp_lib.c
+++ b/crypto/srp/srp_lib.c
@@ -63,13 +63,17 @@
 #include <openssl/evp.h>
 
 #if (BN_BYTES == 8)
-#define bn_pack4(a1,a2,a3,a4) 0x##a1##a2##a3##a4##ul
-#endif
-#if (BN_BYTES == 4)
-#define bn_pack4(a1,a2,a3,a4)  0x##a3##a4##ul, 0x##a1##a2##ul
-#endif
-#if (BN_BYTES == 2)
-#define bn_pack4(a1,a2,a3,a4) 0x##a4##u,0x##a3##u,0x##a2##u,0x##a1##u
+# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
+#  define bn_pack4(a1,a2,a3,a4) ((a1##UI64<<48)|(a2##UI64<<32)|(a3##UI64<<16)|a4##UI64)
+# elif defined(__arch64__)
+#  define bn_pack4(a1,a2,a3,a4) ((a1##UL<<48)|(a2##UL<<32)|(a3##UL<<16)|a4##UL)
+# else
+#  define bn_pack4(a1,a2,a3,a4) ((a1##ULL<<48)|(a2##ULL<<32)|(a3##ULL<<16)|a4##ULL)
+# endif
+#elif (BN_BYTES == 4)
+# define bn_pack4(a1,a2,a3,a4)  ((a3##UL<<16)|a4##UL), ((a1##UL<<16)|a2##UL)
+#else
+# error "unsupported BN_BYTES"
 #endif
 
 
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 12d71f5..5195ffe 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -694,6 +694,7 @@
 	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 @@
 	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 @@
 		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);
diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c
index b94aeeb..e06602d 100644
--- a/crypto/x509/x_all.c
+++ b/crypto/x509/x_all.c
@@ -97,6 +97,7 @@
 
 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_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/crypto/x86cpuid.S b/crypto/x86cpuid.S
index 1ed297f..73b5d98 100644
--- a/crypto/x86cpuid.S
+++ b/crypto/x86cpuid.S
@@ -61,6 +61,7 @@
 	movzbl	%cl,%esi
 	incl	%esi
 	movl	$1,%eax
+	xorl	%ecx,%ecx
 	.byte	0x0f,0xa2
 	btl	$28,%edx
 	jnc	.L002generic
@@ -82,6 +83,7 @@
 	andl	$4095,%edi
 .L003nocacheinfo:
 	movl	$1,%eax
+	xorl	%ecx,%ecx
 	.byte	0x0f,0xa2
 	andl	$3220176895,%edx
 	cmpl	$0,%ebp
diff --git a/crypto/x86cpuid.pl b/crypto/x86cpuid.pl
index c18b0e2..b270b44 100644
--- a/crypto/x86cpuid.pl
+++ b/crypto/x86cpuid.pl
@@ -67,6 +67,7 @@
 	&inc	("esi");		# number of cores
 
 	&mov	("eax",1);
+	&xor	("ecx","ecx");
 	&cpuid	();
 	&bt	("edx",28);
 	&jnc	(&label("generic"));
@@ -91,6 +92,7 @@
 
 &set_label("nocacheinfo");
 	&mov	("eax",1);
+	&xor	("ecx","ecx");
 	&cpuid	();
 	&and	("edx",0xbfefffff);	# force reserved bits #20, #30 to 0
 	&cmp	("ebp",0);
diff --git a/import_openssl.sh b/import_openssl.sh
index 332b6ca..727dd05 100755
--- a/import_openssl.sh
+++ b/import_openssl.sh
@@ -27,6 +27,9 @@
 set -e
 trap  "echo WARNING: Exiting on non-zero subprocess exit code" ERR;
 
+# Make sure we're in the right directory.
+cd $(dirname $0)
+
 # Ensure consistent sorting order / tool output.
 export LANG=C
 export LC_ALL=C
@@ -60,7 +63,7 @@
     die "openssl.version not found"
   fi
 
-  source openssl.version
+  source ./openssl.version
   if [ "$OPENSSL_VERSION" == "" ]; then
     die "Invalid openssl.version; see README.android for more information"
   fi
@@ -72,7 +75,7 @@
     die "openssl.config not found"
   fi
 
-  source openssl.config
+  source ./openssl.config
   if [ "$CONFIGURE_ARGS" == "" -o "$UNNEEDED_SOURCES" == "" -o "$NEEDED_SOURCES" == "" ]; then
     die "Invalid openssl.config; see README.android for more information"
   fi
@@ -173,9 +176,21 @@
   echo "#"
 }
 
+# Run Configure and generate makefile
+# $1: makefile
+# $2: 32 for 32-bit arch, 64 for 64-bit arch
 function generate_build_config_mk() {
-  ./Configure $CONFIGURE_ARGS
+  chmod +x ./Configure
+  if [ $2 -eq "32" ] ; then
+    ./Configure $CONFIGURE_ARGS $CONFIGURE_ARGS_32
+  elif [ $2 -eq "64" ] ; then
+    ./Configure $CONFIGURE_ARGS $CONFIGURE_ARGS_64
+  else
+    die "Unsupported $2-bit arch"
+  fi
   rm -f apps/CA.pl.bak crypto/opensslconf.h.bak
+  mv -f crypto/opensslconf.h crypto/opensslconf-$2.h
+  cp -f crypto/opensslconf-$2.h include/openssl/opensslconf-$2.h
 
   declare -r tmpfile=$(mktemp)
   (grep -e -D Makefile | grep -v CONFIGURE_ARGS= | grep -v OPTIONS= | grep -v -e -DOPENSSL_NO_DEPRECATED) > $tmpfile
@@ -192,10 +207,22 @@
     for cflag in $cflags $depflags; do
       echo "  $cflag \\"
     done
-    echo ""
   ) > $1
 }
 
+# Generate crypto/opensslconf.h file including arch-specific files
+function generate_opensslconf_h() {
+  echo "Generating opensslconf.h"
+  (
+  echo "// Auto-generated - DO NOT EDIT!"
+  echo "#if defined(__LP64__)"
+  echo "#include \"opensslconf-64.h\""
+  echo "#else"
+  echo "#include \"opensslconf-32.h\""
+  echo "#endif"
+  ) > crypto/opensslconf.h
+}
+
 # Return the value of a computed variable name.
 # E.g.:
 #   FOO=foo
@@ -261,7 +288,7 @@
 function generate_config_mk() {
   declare -r output="$1"
   declare -r prefix="$2"
-  declare -r all_archs="arm x86 x86_64 mips"
+  declare -r all_archs="arm arm64 x86 x86_64 mips"
 
   echo "Generating $(basename $output)"
   (
@@ -348,7 +375,9 @@
 
   cd $OPENSSL_DIR
 
-  generate_build_config_mk ../build-config.mk
+  generate_build_config_mk ../build-config-32.mk 32
+  generate_build_config_mk ../build-config-64.mk 64
+  generate_opensslconf_h
 
   cp -f LICENSE ../NOTICE
   touch ../MODULE_LICENSE_BSD_LIKE
@@ -546,12 +575,12 @@
   declare -r patch=$1
 
   # Cleanup stray files before generating patch
-  find $BOUNCYCASTLE_DIR -type f -name "*.orig" -print0 | xargs -0 rm -f
-  find $BOUNCYCASTLE_DIR -type f -name "*~" -print0 | xargs -0 rm -f
+  find $OPENSSL_DIR -type f -name "*.orig" -print0 | xargs -0 rm -f
+  find $OPENSSL_DIR -type f -name "*~" -print0 | xargs -0 rm -f
 
-  declare -r variable_name=OPENSSL_PATCHES_`basename $patch .patch | sed s/-/_/`_SOURCES
-  # http://tldp.org/LDP/abs/html/ivr.html
-  eval declare -r sources=\$$variable_name
+  # Find the files the patch touches and only keep those in the output patch
+  declare -r sources=`patch -p1 --dry-run -d $OPENSSL_DIR < $patch  | awk '/^patching file / { print $3 }'`
+
   rm -f $patch
   touch $patch
   for i in $sources; do
diff --git a/include/openssl/buffer.h b/include/openssl/buffer.h
index 178e418..f8da32b 100644
--- a/include/openssl/buffer.h
+++ b/include/openssl/buffer.h
@@ -88,7 +88,7 @@
 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/include/openssl/cms.h b/include/openssl/cms.h
new file mode 100644
index 0000000..36994fa
--- /dev/null
+++ b/include/openssl/cms.h
@@ -0,0 +1,501 @@
+/* crypto/cms/cms.h */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ */
+
+
+#ifndef HEADER_CMS_H
+#define HEADER_CMS_H
+
+#include <openssl/x509.h>
+
+#ifdef OPENSSL_NO_CMS
+#error CMS is disabled.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct CMS_ContentInfo_st CMS_ContentInfo;
+typedef struct CMS_SignerInfo_st CMS_SignerInfo;
+typedef struct CMS_CertificateChoices CMS_CertificateChoices;
+typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice;
+typedef struct CMS_RecipientInfo_st CMS_RecipientInfo;
+typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest;
+typedef struct CMS_Receipt_st CMS_Receipt;
+
+DECLARE_STACK_OF(CMS_SignerInfo)
+DECLARE_STACK_OF(GENERAL_NAMES)
+DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
+DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest)
+DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
+
+#define CMS_SIGNERINFO_ISSUER_SERIAL	0
+#define CMS_SIGNERINFO_KEYIDENTIFIER	1
+
+#define CMS_RECIPINFO_TRANS		0
+#define CMS_RECIPINFO_AGREE		1
+#define CMS_RECIPINFO_KEK		2
+#define CMS_RECIPINFO_PASS		3
+#define CMS_RECIPINFO_OTHER		4
+
+/* S/MIME related flags */
+
+#define CMS_TEXT			0x1
+#define CMS_NOCERTS			0x2
+#define CMS_NO_CONTENT_VERIFY		0x4
+#define CMS_NO_ATTR_VERIFY		0x8
+#define CMS_NOSIGS			\
+			(CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY)
+#define CMS_NOINTERN			0x10
+#define CMS_NO_SIGNER_CERT_VERIFY	0x20
+#define CMS_NOVERIFY			0x20
+#define CMS_DETACHED			0x40
+#define CMS_BINARY			0x80
+#define CMS_NOATTR			0x100
+#define	CMS_NOSMIMECAP			0x200
+#define CMS_NOOLDMIMETYPE		0x400
+#define CMS_CRLFEOL			0x800
+#define CMS_STREAM			0x1000
+#define CMS_NOCRL			0x2000
+#define CMS_PARTIAL			0x4000
+#define CMS_REUSE_DIGEST		0x8000
+#define CMS_USE_KEYID			0x10000
+#define CMS_DEBUG_DECRYPT		0x20000
+
+const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms);
+
+BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont);
+int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio);
+
+ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms);
+int CMS_is_detached(CMS_ContentInfo *cms);
+int CMS_set_detached(CMS_ContentInfo *cms, int detached);
+
+#ifdef HEADER_PEM_H
+DECLARE_PEM_rw_const(CMS, CMS_ContentInfo)
+#endif
+
+int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms);
+CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms);
+int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms);
+
+BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms);
+int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags);
+int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags);
+CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont);
+int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags);
+
+int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags);
+
+CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
+						BIO *data, unsigned int flags);
+
+CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
+					X509 *signcert, EVP_PKEY *pkey,
+					STACK_OF(X509) *certs,
+					unsigned int flags);
+
+int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags);
+CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags);
+
+int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+							unsigned int flags);
+CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
+							unsigned int flags);
+
+int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
+				const unsigned char *key, size_t keylen,
+				BIO *dcont, BIO *out, unsigned int flags);
+
+CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
+					const unsigned char *key, size_t keylen,
+					unsigned int flags);
+
+int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
+				const unsigned char *key, size_t keylen);
+
+int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
+		 X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags);
+
+int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
+			STACK_OF(X509) *certs,
+			X509_STORE *store, unsigned int flags);
+
+STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
+
+CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
+				const EVP_CIPHER *cipher, unsigned int flags);
+
+int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert,
+				BIO *dcont, BIO *out,
+				unsigned int flags);
+	
+int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert);
+int CMS_decrypt_set1_key(CMS_ContentInfo *cms, 
+				unsigned char *key, size_t keylen,
+				unsigned char *id, size_t idlen);
+int CMS_decrypt_set1_password(CMS_ContentInfo *cms, 
+				unsigned char *pass, ossl_ssize_t passlen);
+
+STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
+int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
+CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
+CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
+					X509 *recip, unsigned int flags);
+int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey);
+int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert);
+int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
+					EVP_PKEY **pk, X509 **recip,
+					X509_ALGOR **palg);
+int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
+					ASN1_OCTET_STRING **keyid,
+					X509_NAME **issuer, ASN1_INTEGER **sno);
+
+CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
+					unsigned char *key, size_t keylen,
+					unsigned char *id, size_t idlen,
+					ASN1_GENERALIZEDTIME *date,
+					ASN1_OBJECT *otherTypeId,
+					ASN1_TYPE *otherType);
+
+int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
+					X509_ALGOR **palg,
+					ASN1_OCTET_STRING **pid,
+					ASN1_GENERALIZEDTIME **pdate,
+					ASN1_OBJECT **potherid,
+					ASN1_TYPE **pothertype);
+
+int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, 
+				unsigned char *key, size_t keylen);
+
+int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, 
+					const unsigned char *id, size_t idlen);
+
+int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, 
+					unsigned char *pass,
+					ossl_ssize_t passlen);
+
+CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
+					int iter, int wrap_nid, int pbe_nid,
+					unsigned char *pass,
+					ossl_ssize_t passlen,
+					const EVP_CIPHER *kekciph);
+
+int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
+	
+int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+							unsigned int flags);
+CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags);
+
+int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid);
+const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms);
+
+CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms);
+int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert);
+int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert);
+STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms);
+
+CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms);
+int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl);
+int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl);
+STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms);
+
+int CMS_SignedData_init(CMS_ContentInfo *cms);
+CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
+			X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
+			unsigned int flags);
+STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms);
+
+void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer);
+int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
+					ASN1_OCTET_STRING **keyid,
+					X509_NAME **issuer, ASN1_INTEGER **sno);
+int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert);
+int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
+					unsigned int flags);
+void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer,
+					X509_ALGOR **pdig, X509_ALGOR **psig);
+int CMS_SignerInfo_sign(CMS_SignerInfo *si);
+int CMS_SignerInfo_verify(CMS_SignerInfo *si);
+int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain);
+
+int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs);
+int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
+				int algnid, int keysize);
+int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap);
+
+int CMS_signed_get_attr_count(const CMS_SignerInfo *si);
+int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+			  int lastpos);
+int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
+			  int lastpos);
+X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc);
+X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc);
+int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
+int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
+			const ASN1_OBJECT *obj, int type,
+			const void *bytes, int len);
+int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
+			int nid, int type,
+			const void *bytes, int len);
+int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
+			const char *attrname, int type,
+			const void *bytes, int len);
+void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
+					int lastpos, int type);
+
+int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si);
+int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+			  int lastpos);
+int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
+			  int lastpos);
+X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc);
+X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc);
+int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
+int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
+			const ASN1_OBJECT *obj, int type,
+			const void *bytes, int len);
+int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
+			int nid, int type,
+			const void *bytes, int len);
+int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
+			const char *attrname, int type,
+			const void *bytes, int len);
+void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
+					int lastpos, int type);
+
+#ifdef HEADER_X509V3_H
+
+int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr);
+CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
+				int allorfirst,
+				STACK_OF(GENERAL_NAMES) *receiptList,
+				STACK_OF(GENERAL_NAMES) *receiptsTo);
+int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr);
+void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
+					ASN1_STRING **pcid,
+					int *pallorfirst,
+					STACK_OF(GENERAL_NAMES) **plist,
+					STACK_OF(GENERAL_NAMES) **prto);
+
+#endif
+
+/* 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.
+ */
+void ERR_load_CMS_strings(void);
+
+/* Error codes for the CMS functions. */
+
+/* Function codes. */
+#define CMS_F_CHECK_CONTENT				 99
+#define CMS_F_CMS_ADD0_CERT				 164
+#define CMS_F_CMS_ADD0_RECIPIENT_KEY			 100
+#define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD		 165
+#define CMS_F_CMS_ADD1_RECEIPTREQUEST			 158
+#define CMS_F_CMS_ADD1_RECIPIENT_CERT			 101
+#define CMS_F_CMS_ADD1_SIGNER				 102
+#define CMS_F_CMS_ADD1_SIGNINGTIME			 103
+#define CMS_F_CMS_COMPRESS				 104
+#define CMS_F_CMS_COMPRESSEDDATA_CREATE			 105
+#define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO		 106
+#define CMS_F_CMS_COPY_CONTENT				 107
+#define CMS_F_CMS_COPY_MESSAGEDIGEST			 108
+#define CMS_F_CMS_DATA					 109
+#define CMS_F_CMS_DATAFINAL				 110
+#define CMS_F_CMS_DATAINIT				 111
+#define CMS_F_CMS_DECRYPT				 112
+#define CMS_F_CMS_DECRYPT_SET1_KEY			 113
+#define CMS_F_CMS_DECRYPT_SET1_PASSWORD			 166
+#define CMS_F_CMS_DECRYPT_SET1_PKEY			 114
+#define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX		 115
+#define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO		 116
+#define CMS_F_CMS_DIGESTEDDATA_DO_FINAL			 117
+#define CMS_F_CMS_DIGEST_VERIFY				 118
+#define CMS_F_CMS_ENCODE_RECEIPT			 161
+#define CMS_F_CMS_ENCRYPT				 119
+#define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO		 120
+#define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT			 121
+#define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT			 122
+#define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY		 123
+#define CMS_F_CMS_ENVELOPEDDATA_CREATE			 124
+#define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO		 125
+#define CMS_F_CMS_ENVELOPED_DATA_INIT			 126
+#define CMS_F_CMS_FINAL					 127
+#define CMS_F_CMS_GET0_CERTIFICATE_CHOICES		 128
+#define CMS_F_CMS_GET0_CONTENT				 129
+#define CMS_F_CMS_GET0_ECONTENT_TYPE			 130
+#define CMS_F_CMS_GET0_ENVELOPED			 131
+#define CMS_F_CMS_GET0_REVOCATION_CHOICES		 132
+#define CMS_F_CMS_GET0_SIGNED				 133
+#define CMS_F_CMS_MSGSIGDIGEST_ADD1			 162
+#define CMS_F_CMS_RECEIPTREQUEST_CREATE0		 159
+#define CMS_F_CMS_RECEIPT_VERIFY			 160
+#define CMS_F_CMS_RECIPIENTINFO_DECRYPT			 134
+#define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT		 135
+#define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT		 136
+#define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID		 137
+#define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP		 138
+#define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP		 139
+#define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT		 140
+#define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT		 141
+#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS		 142
+#define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID	 143
+#define CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT		 167
+#define CMS_F_CMS_RECIPIENTINFO_SET0_KEY		 144
+#define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD		 168
+#define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY		 145
+#define CMS_F_CMS_SET1_SIGNERIDENTIFIER			 146
+#define CMS_F_CMS_SET_DETACHED				 147
+#define CMS_F_CMS_SIGN					 148
+#define CMS_F_CMS_SIGNED_DATA_INIT			 149
+#define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN		 150
+#define CMS_F_CMS_SIGNERINFO_SIGN			 151
+#define CMS_F_CMS_SIGNERINFO_VERIFY			 152
+#define CMS_F_CMS_SIGNERINFO_VERIFY_CERT		 153
+#define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT		 154
+#define CMS_F_CMS_SIGN_RECEIPT				 163
+#define CMS_F_CMS_STREAM				 155
+#define CMS_F_CMS_UNCOMPRESS				 156
+#define CMS_F_CMS_VERIFY				 157
+
+/* Reason codes. */
+#define CMS_R_ADD_SIGNER_ERROR				 99
+#define CMS_R_CERTIFICATE_ALREADY_PRESENT		 175
+#define CMS_R_CERTIFICATE_HAS_NO_KEYID			 160
+#define CMS_R_CERTIFICATE_VERIFY_ERROR			 100
+#define CMS_R_CIPHER_INITIALISATION_ERROR		 101
+#define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR	 102
+#define CMS_R_CMS_DATAFINAL_ERROR			 103
+#define CMS_R_CMS_LIB					 104
+#define CMS_R_CONTENTIDENTIFIER_MISMATCH		 170
+#define CMS_R_CONTENT_NOT_FOUND				 105
+#define CMS_R_CONTENT_TYPE_MISMATCH			 171
+#define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA		 106
+#define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA		 107
+#define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA		 108
+#define CMS_R_CONTENT_VERIFY_ERROR			 109
+#define CMS_R_CTRL_ERROR				 110
+#define CMS_R_CTRL_FAILURE				 111
+#define CMS_R_DECRYPT_ERROR				 112
+#define CMS_R_DIGEST_ERROR				 161
+#define CMS_R_ERROR_GETTING_PUBLIC_KEY			 113
+#define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE	 114
+#define CMS_R_ERROR_SETTING_KEY				 115
+#define CMS_R_ERROR_SETTING_RECIPIENTINFO		 116
+#define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH		 117
+#define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER		 176
+#define CMS_R_INVALID_KEY_LENGTH			 118
+#define CMS_R_MD_BIO_INIT_ERROR				 119
+#define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH	 120
+#define CMS_R_MESSAGEDIGEST_WRONG_LENGTH		 121
+#define CMS_R_MSGSIGDIGEST_ERROR			 172
+#define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE		 162
+#define CMS_R_MSGSIGDIGEST_WRONG_LENGTH			 163
+#define CMS_R_NEED_ONE_SIGNER				 164
+#define CMS_R_NOT_A_SIGNED_RECEIPT			 165
+#define CMS_R_NOT_ENCRYPTED_DATA			 122
+#define CMS_R_NOT_KEK					 123
+#define CMS_R_NOT_KEY_TRANSPORT				 124
+#define CMS_R_NOT_PWRI					 177
+#define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE		 125
+#define CMS_R_NO_CIPHER					 126
+#define CMS_R_NO_CONTENT				 127
+#define CMS_R_NO_CONTENT_TYPE				 173
+#define CMS_R_NO_DEFAULT_DIGEST				 128
+#define CMS_R_NO_DIGEST_SET				 129
+#define CMS_R_NO_KEY					 130
+#define CMS_R_NO_KEY_OR_CERT				 174
+#define CMS_R_NO_MATCHING_DIGEST			 131
+#define CMS_R_NO_MATCHING_RECIPIENT			 132
+#define CMS_R_NO_MATCHING_SIGNATURE			 166
+#define CMS_R_NO_MSGSIGDIGEST				 167
+#define CMS_R_NO_PASSWORD				 178
+#define CMS_R_NO_PRIVATE_KEY				 133
+#define CMS_R_NO_PUBLIC_KEY				 134
+#define CMS_R_NO_RECEIPT_REQUEST			 168
+#define CMS_R_NO_SIGNERS				 135
+#define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE	 136
+#define CMS_R_RECEIPT_DECODE_ERROR			 169
+#define CMS_R_RECIPIENT_ERROR				 137
+#define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND		 138
+#define CMS_R_SIGNFINAL_ERROR				 139
+#define CMS_R_SMIME_TEXT_ERROR				 140
+#define CMS_R_STORE_INIT_ERROR				 141
+#define CMS_R_TYPE_NOT_COMPRESSED_DATA			 142
+#define CMS_R_TYPE_NOT_DATA				 143
+#define CMS_R_TYPE_NOT_DIGESTED_DATA			 144
+#define CMS_R_TYPE_NOT_ENCRYPTED_DATA			 145
+#define CMS_R_TYPE_NOT_ENVELOPED_DATA			 146
+#define CMS_R_UNABLE_TO_FINALIZE_CONTEXT		 147
+#define CMS_R_UNKNOWN_CIPHER				 148
+#define CMS_R_UNKNOWN_DIGEST_ALGORIHM			 149
+#define CMS_R_UNKNOWN_ID				 150
+#define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM		 151
+#define CMS_R_UNSUPPORTED_CONTENT_TYPE			 152
+#define CMS_R_UNSUPPORTED_KEK_ALGORITHM			 153
+#define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM	 179
+#define CMS_R_UNSUPPORTED_RECIPIENT_TYPE		 154
+#define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE		 155
+#define CMS_R_UNSUPPORTED_TYPE				 156
+#define CMS_R_UNWRAP_ERROR				 157
+#define CMS_R_UNWRAP_FAILURE				 180
+#define CMS_R_VERIFICATION_FAILURE			 158
+#define CMS_R_WRAP_ERROR				 159
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/include/openssl/opensslconf-32.h b/include/openssl/opensslconf-32.h
new file mode 100644
index 0000000..d662548
--- /dev/null
+++ b/include/openssl/opensslconf-32.h
@@ -0,0 +1,316 @@
+/* opensslconf.h */
+/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
+
+/* OpenSSL was configured with the following options: */
+#ifndef OPENSSL_DOING_MAKEDEPEND
+
+
+#ifndef OPENSSL_NO_CAMELLIA
+# define OPENSSL_NO_CAMELLIA
+#endif
+#ifndef OPENSSL_NO_CAPIENG
+# define OPENSSL_NO_CAPIENG
+#endif
+#ifndef OPENSSL_NO_CAST
+# define OPENSSL_NO_CAST
+#endif
+#ifndef OPENSSL_NO_DTLS1
+# define OPENSSL_NO_DTLS1
+#endif
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+# define OPENSSL_NO_EC_NISTP_64_GCC_128
+#endif
+#ifndef OPENSSL_NO_GMP
+# define OPENSSL_NO_GMP
+#endif
+#ifndef OPENSSL_NO_GOST
+# define OPENSSL_NO_GOST
+#endif
+#ifndef OPENSSL_NO_HEARTBEATS
+# define OPENSSL_NO_HEARTBEATS
+#endif
+#ifndef OPENSSL_NO_IDEA
+# define OPENSSL_NO_IDEA
+#endif
+#ifndef OPENSSL_NO_JPAKE
+# define OPENSSL_NO_JPAKE
+#endif
+#ifndef OPENSSL_NO_KRB5
+# define OPENSSL_NO_KRB5
+#endif
+#ifndef OPENSSL_NO_MD2
+# define OPENSSL_NO_MD2
+#endif
+#ifndef OPENSSL_NO_MDC2
+# define OPENSSL_NO_MDC2
+#endif
+#ifndef OPENSSL_NO_RC5
+# define OPENSSL_NO_RC5
+#endif
+#ifndef OPENSSL_NO_RDRAND
+# define OPENSSL_NO_RDRAND
+#endif
+#ifndef OPENSSL_NO_RFC3779
+# define OPENSSL_NO_RFC3779
+#endif
+#ifndef OPENSSL_NO_RSAX
+# define OPENSSL_NO_RSAX
+#endif
+#ifndef OPENSSL_NO_SCTP
+# define OPENSSL_NO_SCTP
+#endif
+#ifndef OPENSSL_NO_SEED
+# define OPENSSL_NO_SEED
+#endif
+#ifndef OPENSSL_NO_SHA0
+# define OPENSSL_NO_SHA0
+#endif
+#ifndef OPENSSL_NO_STATIC_ENGINE
+# define OPENSSL_NO_STATIC_ENGINE
+#endif
+#ifndef OPENSSL_NO_STORE
+# define OPENSSL_NO_STORE
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+# define OPENSSL_NO_WHIRLPOOL
+#endif
+
+#endif /* OPENSSL_DOING_MAKEDEPEND */
+
+#ifndef OPENSSL_THREADS
+# define OPENSSL_THREADS
+#endif
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+# define OPENSSL_NO_DYNAMIC_ENGINE
+#endif
+
+/* The OPENSSL_NO_* macros are also defined as NO_* if the application
+   asks for it.  This is a transient feature that is provided for those
+   who haven't had the time to do the appropriate changes in their
+   applications.  */
+#ifdef OPENSSL_ALGORITHM_DEFINES
+# if defined(OPENSSL_NO_CAMELLIA) && !defined(NO_CAMELLIA)
+#  define NO_CAMELLIA
+# endif
+# if defined(OPENSSL_NO_CAPIENG) && !defined(NO_CAPIENG)
+#  define NO_CAPIENG
+# endif
+# if defined(OPENSSL_NO_CAST) && !defined(NO_CAST)
+#  define NO_CAST
+# endif
+# if defined(OPENSSL_NO_DTLS1) && !defined(NO_DTLS1)
+#  define NO_DTLS1
+# endif
+# if defined(OPENSSL_NO_EC_NISTP_64_GCC_128) && !defined(NO_EC_NISTP_64_GCC_128)
+#  define NO_EC_NISTP_64_GCC_128
+# endif
+# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
+#  define NO_GMP
+# endif
+# if defined(OPENSSL_NO_GOST) && !defined(NO_GOST)
+#  define NO_GOST
+# endif
+# if defined(OPENSSL_NO_HEARTBEATS) && !defined(NO_HEARTBEATS)
+#  define NO_HEARTBEATS
+# endif
+# if defined(OPENSSL_NO_IDEA) && !defined(NO_IDEA)
+#  define NO_IDEA
+# endif
+# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE)
+#  define NO_JPAKE
+# endif
+# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5)
+#  define NO_KRB5
+# endif
+# if defined(OPENSSL_NO_MD2) && !defined(NO_MD2)
+#  define NO_MD2
+# endif
+# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
+#  define NO_MDC2
+# endif
+# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
+#  define NO_RC5
+# endif
+# if defined(OPENSSL_NO_RDRAND) && !defined(NO_RDRAND)
+#  define NO_RDRAND
+# endif
+# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779)
+#  define NO_RFC3779
+# endif
+# if defined(OPENSSL_NO_RSAX) && !defined(NO_RSAX)
+#  define NO_RSAX
+# endif
+# if defined(OPENSSL_NO_SCTP) && !defined(NO_SCTP)
+#  define NO_SCTP
+# endif
+# if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)
+#  define NO_SEED
+# endif
+# if defined(OPENSSL_NO_SHA0) && !defined(NO_SHA0)
+#  define NO_SHA0
+# endif
+# if defined(OPENSSL_NO_STATIC_ENGINE) && !defined(NO_STATIC_ENGINE)
+#  define NO_STATIC_ENGINE
+# endif
+# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE)
+#  define NO_STORE
+# endif
+# if defined(OPENSSL_NO_WHIRLPOOL) && !defined(NO_WHIRLPOOL)
+#  define NO_WHIRLPOOL
+# endif
+#endif
+
+/* crypto/opensslconf.h.in */
+
+/* Generate 80386 code? */
+#undef I386_ONLY
+
+#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
+#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
+#define ENGINESDIR "/usr/local/ssl/lib/engines"
+#define OPENSSLDIR "/usr/local/ssl"
+#endif
+#endif
+
+#undef OPENSSL_UNISTD
+#define OPENSSL_UNISTD <unistd.h>
+
+#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
+#define IDEA_INT unsigned int
+#endif
+
+#if defined(HEADER_MD2_H) && !defined(MD2_INT)
+#define MD2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC2_H) && !defined(RC2_INT)
+/* I need to put in a mod for the alpha - eay */
+#define RC2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC4_H)
+#if !defined(RC4_INT)
+/* using int types make the structure larger but make the code faster
+ * on most boxes I have tested - up to %20 faster. */
+/*
+ * I don't know what does "most" mean, but declaring "int" is a must on:
+ * - Intel P6 because partial register stalls are very expensive;
+ * - elder Alpha because it lacks byte load/store instructions;
+ */
+#define RC4_INT unsigned char
+#endif
+#if !defined(RC4_CHUNK)
+/*
+ * This enables code handling data aligned at natural CPU word
+ * boundary. See crypto/rc4/rc4_enc.c for further details.
+ */
+#define RC4_CHUNK unsigned long
+#endif
+#endif
+
+#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
+ * %20 speed up (longs are 8 bytes, int's are 4). */
+#ifndef DES_LONG
+#define DES_LONG unsigned int
+#endif
+#endif
+
+#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
+#define CONFIG_HEADER_BN_H
+#define BN_LLONG
+
+/* Should we define BN_DIV2W here? */
+
+/* Only one for the following should be defined */
+#undef SIXTY_FOUR_BIT_LONG
+#undef SIXTY_FOUR_BIT
+#define THIRTY_TWO_BIT
+#endif
+
+#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
+#define CONFIG_HEADER_RC4_LOCL_H
+/* if this is defined data[i] is used instead of *data, this is a %20
+ * speedup on x86 */
+#undef RC4_INDEX
+#endif
+
+#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
+#define CONFIG_HEADER_BF_LOCL_H
+#define BF_PTR
+#endif /* HEADER_BF_LOCL_H */
+
+#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
+#define CONFIG_HEADER_DES_LOCL_H
+#ifndef DES_DEFAULT_OPTIONS
+/* the following is tweaked from a config script, that is why it is a
+ * protected undef/define */
+#ifndef DES_PTR
+#undef DES_PTR
+#endif
+
+/* This helps C compiler generate the correct code for multiple functional
+ * units.  It reduces register dependancies at the expense of 2 more
+ * registers */
+#ifndef DES_RISC1
+#undef DES_RISC1
+#endif
+
+#ifndef DES_RISC2
+#undef DES_RISC2
+#endif
+
+#if defined(DES_RISC1) && defined(DES_RISC2)
+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
+#endif
+
+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
+ * Very mucy CPU dependant */
+#ifndef DES_UNROLL
+#define DES_UNROLL
+#endif
+
+/* These default values were supplied by
+ * Peter Gutman <pgut001@cs.auckland.ac.nz>
+ * They are only used if nothing else has been defined */
+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
+/* Special defines which change the way the code is built depending on the
+   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
+   even newer MIPS CPU's, but at the moment one size fits all for
+   optimization options.  Older Sparc's work better with only UNROLL, but
+   there's no way to tell at compile time what it is you're running on */
+ 
+#if defined( sun )		/* Newer Sparc's */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#elif defined( __ultrix )	/* Older MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined( __osf1__ )	/* Alpha */
+#  define DES_PTR
+#  define DES_RISC2
+#elif defined ( _AIX )		/* RS6000 */
+  /* Unknown */
+#elif defined( __hpux )		/* HP-PA */
+  /* Unknown */
+#elif defined( __aux )		/* 68K */
+  /* Unknown */
+#elif defined( __dgux )		/* 88K (but P6 in latest boxes) */
+#  define DES_UNROLL
+#elif defined( __sgi )		/* Newer MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined(i386) || defined(__i386__)	/* x86 boxes, should be gcc */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#endif /* Systems-specific speed defines */
+#endif
+
+#endif /* DES_DEFAULT_OPTIONS */
+#endif /* HEADER_DES_LOCL_H */
diff --git a/include/openssl/opensslconf-64.h b/include/openssl/opensslconf-64.h
new file mode 100644
index 0000000..70c5a2c
--- /dev/null
+++ b/include/openssl/opensslconf-64.h
@@ -0,0 +1,316 @@
+/* opensslconf.h */
+/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
+
+/* OpenSSL was configured with the following options: */
+#ifndef OPENSSL_DOING_MAKEDEPEND
+
+
+#ifndef OPENSSL_NO_CAMELLIA
+# define OPENSSL_NO_CAMELLIA
+#endif
+#ifndef OPENSSL_NO_CAPIENG
+# define OPENSSL_NO_CAPIENG
+#endif
+#ifndef OPENSSL_NO_CAST
+# define OPENSSL_NO_CAST
+#endif
+#ifndef OPENSSL_NO_DTLS1
+# define OPENSSL_NO_DTLS1
+#endif
+#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+# define OPENSSL_NO_EC_NISTP_64_GCC_128
+#endif
+#ifndef OPENSSL_NO_GMP
+# define OPENSSL_NO_GMP
+#endif
+#ifndef OPENSSL_NO_GOST
+# define OPENSSL_NO_GOST
+#endif
+#ifndef OPENSSL_NO_HEARTBEATS
+# define OPENSSL_NO_HEARTBEATS
+#endif
+#ifndef OPENSSL_NO_IDEA
+# define OPENSSL_NO_IDEA
+#endif
+#ifndef OPENSSL_NO_JPAKE
+# define OPENSSL_NO_JPAKE
+#endif
+#ifndef OPENSSL_NO_KRB5
+# define OPENSSL_NO_KRB5
+#endif
+#ifndef OPENSSL_NO_MD2
+# define OPENSSL_NO_MD2
+#endif
+#ifndef OPENSSL_NO_MDC2
+# define OPENSSL_NO_MDC2
+#endif
+#ifndef OPENSSL_NO_RC5
+# define OPENSSL_NO_RC5
+#endif
+#ifndef OPENSSL_NO_RDRAND
+# define OPENSSL_NO_RDRAND
+#endif
+#ifndef OPENSSL_NO_RFC3779
+# define OPENSSL_NO_RFC3779
+#endif
+#ifndef OPENSSL_NO_RSAX
+# define OPENSSL_NO_RSAX
+#endif
+#ifndef OPENSSL_NO_SCTP
+# define OPENSSL_NO_SCTP
+#endif
+#ifndef OPENSSL_NO_SEED
+# define OPENSSL_NO_SEED
+#endif
+#ifndef OPENSSL_NO_SHA0
+# define OPENSSL_NO_SHA0
+#endif
+#ifndef OPENSSL_NO_STATIC_ENGINE
+# define OPENSSL_NO_STATIC_ENGINE
+#endif
+#ifndef OPENSSL_NO_STORE
+# define OPENSSL_NO_STORE
+#endif
+#ifndef OPENSSL_NO_WHIRLPOOL
+# define OPENSSL_NO_WHIRLPOOL
+#endif
+
+#endif /* OPENSSL_DOING_MAKEDEPEND */
+
+#ifndef OPENSSL_THREADS
+# define OPENSSL_THREADS
+#endif
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+# define OPENSSL_NO_DYNAMIC_ENGINE
+#endif
+
+/* The OPENSSL_NO_* macros are also defined as NO_* if the application
+   asks for it.  This is a transient feature that is provided for those
+   who haven't had the time to do the appropriate changes in their
+   applications.  */
+#ifdef OPENSSL_ALGORITHM_DEFINES
+# if defined(OPENSSL_NO_CAMELLIA) && !defined(NO_CAMELLIA)
+#  define NO_CAMELLIA
+# endif
+# if defined(OPENSSL_NO_CAPIENG) && !defined(NO_CAPIENG)
+#  define NO_CAPIENG
+# endif
+# if defined(OPENSSL_NO_CAST) && !defined(NO_CAST)
+#  define NO_CAST
+# endif
+# if defined(OPENSSL_NO_DTLS1) && !defined(NO_DTLS1)
+#  define NO_DTLS1
+# endif
+# if defined(OPENSSL_NO_EC_NISTP_64_GCC_128) && !defined(NO_EC_NISTP_64_GCC_128)
+#  define NO_EC_NISTP_64_GCC_128
+# endif
+# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
+#  define NO_GMP
+# endif
+# if defined(OPENSSL_NO_GOST) && !defined(NO_GOST)
+#  define NO_GOST
+# endif
+# if defined(OPENSSL_NO_HEARTBEATS) && !defined(NO_HEARTBEATS)
+#  define NO_HEARTBEATS
+# endif
+# if defined(OPENSSL_NO_IDEA) && !defined(NO_IDEA)
+#  define NO_IDEA
+# endif
+# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE)
+#  define NO_JPAKE
+# endif
+# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5)
+#  define NO_KRB5
+# endif
+# if defined(OPENSSL_NO_MD2) && !defined(NO_MD2)
+#  define NO_MD2
+# endif
+# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
+#  define NO_MDC2
+# endif
+# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
+#  define NO_RC5
+# endif
+# if defined(OPENSSL_NO_RDRAND) && !defined(NO_RDRAND)
+#  define NO_RDRAND
+# endif
+# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779)
+#  define NO_RFC3779
+# endif
+# if defined(OPENSSL_NO_RSAX) && !defined(NO_RSAX)
+#  define NO_RSAX
+# endif
+# if defined(OPENSSL_NO_SCTP) && !defined(NO_SCTP)
+#  define NO_SCTP
+# endif
+# if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)
+#  define NO_SEED
+# endif
+# if defined(OPENSSL_NO_SHA0) && !defined(NO_SHA0)
+#  define NO_SHA0
+# endif
+# if defined(OPENSSL_NO_STATIC_ENGINE) && !defined(NO_STATIC_ENGINE)
+#  define NO_STATIC_ENGINE
+# endif
+# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE)
+#  define NO_STORE
+# endif
+# if defined(OPENSSL_NO_WHIRLPOOL) && !defined(NO_WHIRLPOOL)
+#  define NO_WHIRLPOOL
+# endif
+#endif
+
+/* crypto/opensslconf.h.in */
+
+/* Generate 80386 code? */
+#undef I386_ONLY
+
+#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
+#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
+#define ENGINESDIR "/usr/local/ssl/lib/engines"
+#define OPENSSLDIR "/usr/local/ssl"
+#endif
+#endif
+
+#undef OPENSSL_UNISTD
+#define OPENSSL_UNISTD <unistd.h>
+
+#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
+#define IDEA_INT unsigned int
+#endif
+
+#if defined(HEADER_MD2_H) && !defined(MD2_INT)
+#define MD2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC2_H) && !defined(RC2_INT)
+/* I need to put in a mod for the alpha - eay */
+#define RC2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC4_H)
+#if !defined(RC4_INT)
+/* using int types make the structure larger but make the code faster
+ * on most boxes I have tested - up to %20 faster. */
+/*
+ * I don't know what does "most" mean, but declaring "int" is a must on:
+ * - Intel P6 because partial register stalls are very expensive;
+ * - elder Alpha because it lacks byte load/store instructions;
+ */
+#define RC4_INT unsigned char
+#endif
+#if !defined(RC4_CHUNK)
+/*
+ * This enables code handling data aligned at natural CPU word
+ * boundary. See crypto/rc4/rc4_enc.c for further details.
+ */
+#define RC4_CHUNK unsigned long
+#endif
+#endif
+
+#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
+ * %20 speed up (longs are 8 bytes, int's are 4). */
+#ifndef DES_LONG
+#define DES_LONG unsigned int
+#endif
+#endif
+
+#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
+#define CONFIG_HEADER_BN_H
+#undef BN_LLONG
+
+/* Should we define BN_DIV2W here? */
+
+/* Only one for the following should be defined */
+#define SIXTY_FOUR_BIT_LONG
+#undef SIXTY_FOUR_BIT
+#undef THIRTY_TWO_BIT
+#endif
+
+#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
+#define CONFIG_HEADER_RC4_LOCL_H
+/* if this is defined data[i] is used instead of *data, this is a %20
+ * speedup on x86 */
+#undef RC4_INDEX
+#endif
+
+#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
+#define CONFIG_HEADER_BF_LOCL_H
+#define BF_PTR
+#endif /* HEADER_BF_LOCL_H */
+
+#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
+#define CONFIG_HEADER_DES_LOCL_H
+#ifndef DES_DEFAULT_OPTIONS
+/* the following is tweaked from a config script, that is why it is a
+ * protected undef/define */
+#ifndef DES_PTR
+#undef DES_PTR
+#endif
+
+/* This helps C compiler generate the correct code for multiple functional
+ * units.  It reduces register dependancies at the expense of 2 more
+ * registers */
+#ifndef DES_RISC1
+#undef DES_RISC1
+#endif
+
+#ifndef DES_RISC2
+#undef DES_RISC2
+#endif
+
+#if defined(DES_RISC1) && defined(DES_RISC2)
+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
+#endif
+
+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
+ * Very mucy CPU dependant */
+#ifndef DES_UNROLL
+#define DES_UNROLL
+#endif
+
+/* These default values were supplied by
+ * Peter Gutman <pgut001@cs.auckland.ac.nz>
+ * They are only used if nothing else has been defined */
+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
+/* Special defines which change the way the code is built depending on the
+   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
+   even newer MIPS CPU's, but at the moment one size fits all for
+   optimization options.  Older Sparc's work better with only UNROLL, but
+   there's no way to tell at compile time what it is you're running on */
+ 
+#if defined( sun )		/* Newer Sparc's */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#elif defined( __ultrix )	/* Older MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined( __osf1__ )	/* Alpha */
+#  define DES_PTR
+#  define DES_RISC2
+#elif defined ( _AIX )		/* RS6000 */
+  /* Unknown */
+#elif defined( __hpux )		/* HP-PA */
+  /* Unknown */
+#elif defined( __aux )		/* 68K */
+  /* Unknown */
+#elif defined( __dgux )		/* 88K (but P6 in latest boxes) */
+#  define DES_UNROLL
+#elif defined( __sgi )		/* Newer MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined(i386) || defined(__i386__)	/* x86 boxes, should be gcc */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#endif /* Systems-specific speed defines */
+#endif
+
+#endif /* DES_DEFAULT_OPTIONS */
+#endif /* HEADER_DES_LOCL_H */
diff --git a/include/openssl/opensslconf.h b/include/openssl/opensslconf.h
index 6149d3e..d00590b 100644
--- a/include/openssl/opensslconf.h
+++ b/include/openssl/opensslconf.h
@@ -1,322 +1,6 @@
-/* opensslconf.h */
-/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
-
-/* OpenSSL was configured with the following options: */
-#ifndef OPENSSL_DOING_MAKEDEPEND
-
-
-#ifndef OPENSSL_NO_CAMELLIA
-# define OPENSSL_NO_CAMELLIA
+// Auto-generated - DO NOT EDIT!
+#if defined(__LP64__)
+#include "opensslconf-64.h"
+#else
+#include "opensslconf-32.h"
 #endif
-#ifndef OPENSSL_NO_CAPIENG
-# define OPENSSL_NO_CAPIENG
-#endif
-#ifndef OPENSSL_NO_CAST
-# define OPENSSL_NO_CAST
-#endif
-#ifndef OPENSSL_NO_CMS
-# define OPENSSL_NO_CMS
-#endif
-#ifndef OPENSSL_NO_DTLS1
-# define OPENSSL_NO_DTLS1
-#endif
-#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
-# define OPENSSL_NO_EC_NISTP_64_GCC_128
-#endif
-#ifndef OPENSSL_NO_GMP
-# define OPENSSL_NO_GMP
-#endif
-#ifndef OPENSSL_NO_GOST
-# define OPENSSL_NO_GOST
-#endif
-#ifndef OPENSSL_NO_HEARTBEATS
-# define OPENSSL_NO_HEARTBEATS
-#endif
-#ifndef OPENSSL_NO_IDEA
-# define OPENSSL_NO_IDEA
-#endif
-#ifndef OPENSSL_NO_JPAKE
-# define OPENSSL_NO_JPAKE
-#endif
-#ifndef OPENSSL_NO_KRB5
-# define OPENSSL_NO_KRB5
-#endif
-#ifndef OPENSSL_NO_MD2
-# define OPENSSL_NO_MD2
-#endif
-#ifndef OPENSSL_NO_MDC2
-# define OPENSSL_NO_MDC2
-#endif
-#ifndef OPENSSL_NO_RC5
-# define OPENSSL_NO_RC5
-#endif
-#ifndef OPENSSL_NO_RDRAND
-# define OPENSSL_NO_RDRAND
-#endif
-#ifndef OPENSSL_NO_RFC3779
-# define OPENSSL_NO_RFC3779
-#endif
-#ifndef OPENSSL_NO_RSAX
-# define OPENSSL_NO_RSAX
-#endif
-#ifndef OPENSSL_NO_SCTP
-# define OPENSSL_NO_SCTP
-#endif
-#ifndef OPENSSL_NO_SEED
-# define OPENSSL_NO_SEED
-#endif
-#ifndef OPENSSL_NO_SHA0
-# define OPENSSL_NO_SHA0
-#endif
-#ifndef OPENSSL_NO_STATIC_ENGINE
-# define OPENSSL_NO_STATIC_ENGINE
-#endif
-#ifndef OPENSSL_NO_STORE
-# define OPENSSL_NO_STORE
-#endif
-#ifndef OPENSSL_NO_WHIRLPOOL
-# define OPENSSL_NO_WHIRLPOOL
-#endif
-
-#endif /* OPENSSL_DOING_MAKEDEPEND */
-
-#ifndef OPENSSL_THREADS
-# define OPENSSL_THREADS
-#endif
-#ifndef OPENSSL_NO_DYNAMIC_ENGINE
-# define OPENSSL_NO_DYNAMIC_ENGINE
-#endif
-
-/* The OPENSSL_NO_* macros are also defined as NO_* if the application
-   asks for it.  This is a transient feature that is provided for those
-   who haven't had the time to do the appropriate changes in their
-   applications.  */
-#ifdef OPENSSL_ALGORITHM_DEFINES
-# if defined(OPENSSL_NO_CAMELLIA) && !defined(NO_CAMELLIA)
-#  define NO_CAMELLIA
-# endif
-# if defined(OPENSSL_NO_CAPIENG) && !defined(NO_CAPIENG)
-#  define NO_CAPIENG
-# endif
-# if defined(OPENSSL_NO_CAST) && !defined(NO_CAST)
-#  define NO_CAST
-# endif
-# if defined(OPENSSL_NO_CMS) && !defined(NO_CMS)
-#  define NO_CMS
-# endif
-# if defined(OPENSSL_NO_DTLS1) && !defined(NO_DTLS1)
-#  define NO_DTLS1
-# endif
-# if defined(OPENSSL_NO_EC_NISTP_64_GCC_128) && !defined(NO_EC_NISTP_64_GCC_128)
-#  define NO_EC_NISTP_64_GCC_128
-# endif
-# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
-#  define NO_GMP
-# endif
-# if defined(OPENSSL_NO_GOST) && !defined(NO_GOST)
-#  define NO_GOST
-# endif
-# if defined(OPENSSL_NO_HEARTBEATS) && !defined(NO_HEARTBEATS)
-#  define NO_HEARTBEATS
-# endif
-# if defined(OPENSSL_NO_IDEA) && !defined(NO_IDEA)
-#  define NO_IDEA
-# endif
-# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE)
-#  define NO_JPAKE
-# endif
-# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5)
-#  define NO_KRB5
-# endif
-# if defined(OPENSSL_NO_MD2) && !defined(NO_MD2)
-#  define NO_MD2
-# endif
-# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
-#  define NO_MDC2
-# endif
-# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
-#  define NO_RC5
-# endif
-# if defined(OPENSSL_NO_RDRAND) && !defined(NO_RDRAND)
-#  define NO_RDRAND
-# endif
-# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779)
-#  define NO_RFC3779
-# endif
-# if defined(OPENSSL_NO_RSAX) && !defined(NO_RSAX)
-#  define NO_RSAX
-# endif
-# if defined(OPENSSL_NO_SCTP) && !defined(NO_SCTP)
-#  define NO_SCTP
-# endif
-# if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)
-#  define NO_SEED
-# endif
-# if defined(OPENSSL_NO_SHA0) && !defined(NO_SHA0)
-#  define NO_SHA0
-# endif
-# if defined(OPENSSL_NO_STATIC_ENGINE) && !defined(NO_STATIC_ENGINE)
-#  define NO_STATIC_ENGINE
-# endif
-# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE)
-#  define NO_STORE
-# endif
-# if defined(OPENSSL_NO_WHIRLPOOL) && !defined(NO_WHIRLPOOL)
-#  define NO_WHIRLPOOL
-# endif
-#endif
-
-/* crypto/opensslconf.h.in */
-
-/* Generate 80386 code? */
-#undef I386_ONLY
-
-#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
-#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
-#define ENGINESDIR "/usr/local/ssl/lib/engines"
-#define OPENSSLDIR "/usr/local/ssl"
-#endif
-#endif
-
-#undef OPENSSL_UNISTD
-#define OPENSSL_UNISTD <unistd.h>
-
-#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
-
-#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
-#define IDEA_INT unsigned int
-#endif
-
-#if defined(HEADER_MD2_H) && !defined(MD2_INT)
-#define MD2_INT unsigned int
-#endif
-
-#if defined(HEADER_RC2_H) && !defined(RC2_INT)
-/* I need to put in a mod for the alpha - eay */
-#define RC2_INT unsigned int
-#endif
-
-#if defined(HEADER_RC4_H)
-#if !defined(RC4_INT)
-/* using int types make the structure larger but make the code faster
- * on most boxes I have tested - up to %20 faster. */
-/*
- * I don't know what does "most" mean, but declaring "int" is a must on:
- * - Intel P6 because partial register stalls are very expensive;
- * - elder Alpha because it lacks byte load/store instructions;
- */
-#define RC4_INT unsigned char
-#endif
-#if !defined(RC4_CHUNK)
-/*
- * This enables code handling data aligned at natural CPU word
- * boundary. See crypto/rc4/rc4_enc.c for further details.
- */
-#define RC4_CHUNK unsigned long
-#endif
-#endif
-
-#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
-/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
- * %20 speed up (longs are 8 bytes, int's are 4). */
-#ifndef DES_LONG
-#define DES_LONG unsigned int
-#endif
-#endif
-
-#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
-#define CONFIG_HEADER_BN_H
-#define BN_LLONG
-
-/* Should we define BN_DIV2W here? */
-
-/* Only one for the following should be defined */
-#undef SIXTY_FOUR_BIT_LONG
-#undef SIXTY_FOUR_BIT
-#define THIRTY_TWO_BIT
-#endif
-
-#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
-#define CONFIG_HEADER_RC4_LOCL_H
-/* if this is defined data[i] is used instead of *data, this is a %20
- * speedup on x86 */
-#undef RC4_INDEX
-#endif
-
-#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
-#define CONFIG_HEADER_BF_LOCL_H
-#define BF_PTR
-#endif /* HEADER_BF_LOCL_H */
-
-#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
-#define CONFIG_HEADER_DES_LOCL_H
-#ifndef DES_DEFAULT_OPTIONS
-/* the following is tweaked from a config script, that is why it is a
- * protected undef/define */
-#ifndef DES_PTR
-#undef DES_PTR
-#endif
-
-/* This helps C compiler generate the correct code for multiple functional
- * units.  It reduces register dependancies at the expense of 2 more
- * registers */
-#ifndef DES_RISC1
-#undef DES_RISC1
-#endif
-
-#ifndef DES_RISC2
-#undef DES_RISC2
-#endif
-
-#if defined(DES_RISC1) && defined(DES_RISC2)
-YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
-#endif
-
-/* Unroll the inner loop, this sometimes helps, sometimes hinders.
- * Very mucy CPU dependant */
-#ifndef DES_UNROLL
-#define DES_UNROLL
-#endif
-
-/* These default values were supplied by
- * Peter Gutman <pgut001@cs.auckland.ac.nz>
- * They are only used if nothing else has been defined */
-#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
-/* Special defines which change the way the code is built depending on the
-   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
-   even newer MIPS CPU's, but at the moment one size fits all for
-   optimization options.  Older Sparc's work better with only UNROLL, but
-   there's no way to tell at compile time what it is you're running on */
- 
-#if defined( sun )		/* Newer Sparc's */
-#  define DES_PTR
-#  define DES_RISC1
-#  define DES_UNROLL
-#elif defined( __ultrix )	/* Older MIPS */
-#  define DES_PTR
-#  define DES_RISC2
-#  define DES_UNROLL
-#elif defined( __osf1__ )	/* Alpha */
-#  define DES_PTR
-#  define DES_RISC2
-#elif defined ( _AIX )		/* RS6000 */
-  /* Unknown */
-#elif defined( __hpux )		/* HP-PA */
-  /* Unknown */
-#elif defined( __aux )		/* 68K */
-  /* Unknown */
-#elif defined( __dgux )		/* 88K (but P6 in latest boxes) */
-#  define DES_UNROLL
-#elif defined( __sgi )		/* Newer MIPS */
-#  define DES_PTR
-#  define DES_RISC2
-#  define DES_UNROLL
-#elif defined(i386) || defined(__i386__)	/* x86 boxes, should be gcc */
-#  define DES_PTR
-#  define DES_RISC1
-#  define DES_UNROLL
-#endif /* Systems-specific speed defines */
-#endif
-
-#endif /* DES_DEFAULT_OPTIONS */
-#endif /* HEADER_DES_LOCL_H */
diff --git a/include/openssl/opensslv.h b/include/openssl/opensslv.h
index 5bc8e53..b27a5bb 100644
--- a/include/openssl/opensslv.h
+++ b/include/openssl/opensslv.h
@@ -25,11 +25,11 @@
  * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
  *  major minor fix final patch/beta)
  */
-#define OPENSSL_VERSION_NUMBER	0x1000105fL
+#define OPENSSL_VERSION_NUMBER	0x1000106fL
 #ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1e-fips 11 Feb 2013"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1f-fips 6 Jan 2014"
 #else
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1e 11 Feb 2013"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1f 6 Jan 2014"
 #endif
 #define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
 
diff --git a/include/openssl/rand.h b/include/openssl/rand.h
index dc8fcf9..bb5520e 100644
--- a/include/openssl/rand.h
+++ b/include/openssl/rand.h
@@ -138,6 +138,7 @@
 #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/include/openssl/ssl.h b/include/openssl/ssl.h
index 89d5267..e2e97f1 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -555,16 +555,23 @@
 #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
 
-/* 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
- * implementations cannot handle it at all, which is why we include
- * it in SSL_OP_ALL. */
+/* Hasn't done anything since OpenSSL 0.9.7h, retained for compatibility */
+#define SSL_OP_MSIE_SSLV2_RSA_PADDING			0x0
+
+/* SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS is vestigial. Previously it disabled the
+ * insertion of empty records in CBC mode, but the empty records were commonly
+ * misinterpreted as EOF by other TLS stacks and so this was disabled by
+ * SSL_OP_ALL.
+ *
+ * This has been replaced by 1/n-1 record splitting, which is enabled by
+ * SSL_MODE_CBC_RECORD_SPLITTING in SSL_set_mode. This involves sending a
+ * one-byte record rather than an empty record and has much better
+ * compatibility. */
 #define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS              0x00000800L /* added in 0.9.6e */
 
 /* SSL_OP_ALL: various bug workarounds that should be rather harmless.
@@ -641,10 +648,21 @@
  * 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
 /* When set, clients may send application data before receipt of CCS
  * and Finished.  This mode enables full-handshakes to 'complete' in
  * one RTT. */
-#define SSL_MODE_HANDSHAKE_CUTTHROUGH 0x00000020L
+#define SSL_MODE_HANDSHAKE_CUTTHROUGH 0x00000080L
+/* When set, TLS 1.0 and SSLv3, multi-byte, CBC records will be split in two:
+ * the first record will contain a single byte and the second will contain the
+ * rest of the bytes. This effectively randomises the IV and prevents BEAST
+ * attacks. */
+#define SSL_MODE_CBC_RECORD_SPLITTING 0x00000100L
 
 /* Send TLS_FALLBACK_SCSV in the ClientHello.
  * To be set by applications that reconnect with a downgraded protocol
diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h
index 555e1e9..1aa4023 100644
--- a/include/openssl/ssl3.h
+++ b/include/openssl/ssl3.h
@@ -427,8 +427,8 @@
 	unsigned char client_random[SSL3_RANDOM_SIZE];
 
 	/* flags for countermeasure against known-IV weakness */
-	int need_empty_fragments;
-	int empty_fragment_done;
+	int need_record_splitting;
+	int record_split_done;
 
 	/* The value of 'extra' when the buffers were initialized */
 	int init_extra;
@@ -549,6 +549,15 @@
 	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 */
+
 	/* In a client, this means that the server supported Channel ID and that
 	 * a Channel ID was sent. In a server it means that we echoed support
 	 * for Channel IDs and that tlsext_channel_id will be valid after the
diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h
index f798556..86507d7 100644
--- a/include/openssl/tls1.h
+++ b/include/openssl/tls1.h
@@ -257,6 +257,10 @@
 /* This is not an IANA defined extension number */
 #define TLSEXT_TYPE_channel_id			30031
 
+/* See https://tools.ietf.org/html/draft-agl-tls-padding-02
+ * Number not yet IANA assigned. */
+#define TLSEXT_TYPE_padding			35655
+
 /* NameType value from RFC 3546 */
 #define TLSEXT_NAMETYPE_host_name 0
 /* status request value from RFC 3546 */
diff --git a/openssl.config b/openssl.config
index 06f3b89..e3c690d 100644
--- a/openssl.config
+++ b/openssl.config
@@ -1,10 +1,8 @@
 CONFIGURE_ARGS="\
 -DL_ENDIAN \
-linux-generic32 \
 no-camellia \
 no-capieng \
 no-cast \
-no-cms \
 no-dtls1 \
 no-gost \
 no-gmp \
@@ -24,6 +22,16 @@
 no-whirlpool \
 "
 
+# configure arguments specific for 32-bit arch
+CONFIGURE_ARGS_32="\
+linux-generic32 \
+"
+
+# configure arguments specific for 64-bit arch
+CONFIGURE_ARGS_64="\
+linux-generic64 \
+"
+
 # unneeded directories
 UNNEEDED_SOURCES="\
 MacOS \
@@ -36,7 +44,6 @@
 certs \
 crypto/camellia \
 crypto/cast \
-crypto/cms \
 crypto/idea \
 crypto/md2 \
 crypto/rc5 \
@@ -81,6 +88,7 @@
 README.ENGINE \
 apps/CA.com \
 apps/Makefile \
+apps/Makefile.save \
 apps/install-apps.com \
 apps/makeapps.com \
 apps/openssl-vms.cnf \
@@ -90,11 +98,15 @@
 config \
 crypto/LPdir_vms.c \
 crypto/Makefile \
+crypto/Makefile.save \
 crypto/aes/Makefile \
+crypto/aes/Makefile.save \
 crypto/armcap.c \
 crypto/asn1/Makefile \
+crypto/asn1/Makefile.save \
 crypto/bf/INSTALL \
 crypto/bf/Makefile \
+crypto/bf/Makefile.save \
 crypto/bf/README \
 crypto/bf/VERSION \
 crypto/bf/asm/readme \
@@ -104,77 +116,117 @@
 crypto/bf/bfspeed.c \
 crypto/bf/bftest.c \
 crypto/bio/Makefile \
+crypto/bio/Makefile.save \
 crypto/bio/bss_rtcp.c \
 crypto/bn/Makefile \
+crypto/bn/Makefile.save \
 crypto/bn/asm/vms.mar \
 crypto/bn/bn_x931p.c \
 crypto/bn/vms-helper.c \
 crypto/buffer/Makefile \
+crypto/buffer/Makefile.save \
 crypto/cmac/Makefile \
+crypto/cmac/Makefile.save \
+crypto/cms/Makefile \
+crypto/cms/Makefile.save \
 crypto/comp/Makefile \
+crypto/comp/Makefile.save \
 crypto/conf/Makefile \
+crypto/conf/Makefile.save \
 crypto/crypto-lib.com \
 crypto/des/Makefile \
+crypto/des/Makefile.save \
 crypto/des/des-lib.com \
 crypto/dh/Makefile \
+crypto/dh/Makefile.save \
 crypto/dh/dh_prn.c \
 crypto/dsa/Makefile \
+crypto/dsa/Makefile.save \
 crypto/dso/Makefile \
+crypto/dso/Makefile.save \
 crypto/dso/dso_beos.c \
 crypto/dso/dso_vms.c \
 crypto/dso/dso_win32.c \
 crypto/ec/Makefile \
+crypto/ec/Makefile.save \
 crypto/ec/ecp_nistp224.c \
 crypto/ec/ecp_nistp256.c \
 crypto/ec/ecp_nistp521.c \
 crypto/ec/ecp_nistputil.c \
 crypto/ecdh/Makefile \
+crypto/ecdh/Makefile.save \
 crypto/ecdsa/Makefile \
+crypto/ecdsa/Makefile.save \
 crypto/engine/Makefile \
+crypto/engine/Makefile.save \
 crypto/engine/eng_rdrand.c \
 crypto/engine/eng_rsax.c \
 crypto/err/Makefile \
+crypto/err/Makefile.save \
 crypto/evp/Makefile \
+crypto/evp/Makefile.save \
 crypto/evp/evp_fips.c \
 crypto/evp/m_md2.c \
 crypto/evp/m_sha.c \
 crypto/fips_err.h \
 crypto/fips_ers.c \
 crypto/hmac/Makefile \
+crypto/hmac/Makefile.save \
 crypto/install-crypto.com \
 crypto/jpake/Makefile \
 crypto/krb5/Makefile \
+crypto/krb5/Makefile.save \
 crypto/lhash/Makefile \
+crypto/lhash/Makefile.save \
 crypto/md4/Makefile \
+crypto/md4/Makefile.save \
 crypto/md5/Makefile \
+crypto/md5/Makefile.save \
 crypto/mdc2/Makefile \
+crypto/mdc2/Makefile.save \
 crypto/modes/Makefile \
+crypto/modes/Makefile.save \
 crypto/modes/cts128.c \
 crypto/modes/modes.h \
 crypto/o_fips.c \
 crypto/objects/Makefile \
+crypto/objects/Makefile.save \
 crypto/ocsp/Makefile \
+crypto/ocsp/Makefile.save \
 crypto/pem/Makefile \
+crypto/pem/Makefile.save \
 crypto/pkcs12/Makefile \
+crypto/pkcs12/Makefile.save \
 crypto/pkcs7/Makefile \
+crypto/pkcs7/Makefile.save \
 crypto/pkcs7/bio_pk7.c \
 crypto/ppccap.c \
 crypto/pqueue/Makefile \
+crypto/pqueue/Makefile.save \
 crypto/rand/Makefile \
+crypto/rand/Makefile.save \
 crypto/rand/rand_vms.c \
 crypto/rc2/Makefile \
+crypto/rc2/Makefile.save \
 crypto/rc4/Makefile \
+crypto/rc4/Makefile.save \
 crypto/ripemd/Makefile \
+crypto/ripemd/Makefile.save \
 crypto/rsa/Makefile \
+crypto/rsa/Makefile.save \
 crypto/sha/Makefile \
+crypto/sha/Makefile.save \
 crypto/sha/sha_one.c \
 crypto/srp/Makefile \
+crypto/srp/Makefile.save \
 crypto/srp/srptest.c \
 crypto/stack/Makefile \
+crypto/stack/Makefile.save \
 crypto/store/Makefile \
 crypto/threads/pthreads-vms.com \
 crypto/threads/win32.bat \
 crypto/ts/Makefile \
+crypto/ts/Makefile.save \
 crypto/ts/ts.h \
 crypto/ts/ts_asn1.c \
 crypto/ts/ts_conf.c \
@@ -187,13 +239,16 @@
 crypto/ts/ts_rsp_verify.c \
 crypto/ts/ts_verify_ctx.c \
 crypto/txt_db/Makefile \
+crypto/txt_db/Makefile.save \
 crypto/ui/Makefile \
+crypto/ui/Makefile.save \
 crypto/vms_rms.h
 crypto/x509/Makefile \
+crypto/x509/Makefile.save \
 crypto/x509v3/Makefile \
+crypto/x509v3/Makefile.save \
 include/openssl/camellia.h \
 include/openssl/cast.h \
-include/openssl/cms.h \
 include/openssl/idea.h \
 include/openssl/mdc2.h \
 include/openssl/seed.h \
@@ -203,6 +258,7 @@
 openssl.doxy \
 openssl.spec \
 ssl/Makefile \
+ssl/Makefile.save \
 ssl/install-ssl.com \
 ssl/ssl-lib.com \
 ssl/ssl_task.c \
@@ -233,6 +289,10 @@
 SHA512_ASM \
 "
 
+OPENSSL_CRYPTO_DEFINES_arm64="\
+OPENSSL_NO_ASM \
+"
+
 OPENSSL_CRYPTO_DEFINES_mips="\
 OPENSSL_BN_ASM_MONT \
 AES_ASM \
@@ -436,6 +496,19 @@
 crypto/cmac/cm_ameth.c \
 crypto/cmac/cm_pmeth.c \
 crypto/cmac/cmac.c \
+crypto/cms/cms_asn1.c \
+crypto/cms/cms_att.c \
+crypto/cms/cms_cd.c \
+crypto/cms/cms_dd.c \
+crypto/cms/cms_enc.c \
+crypto/cms/cms_env.c \
+crypto/cms/cms_err.c \
+crypto/cms/cms_ess.c \
+crypto/cms/cms_io.c \
+crypto/cms/cms_lib.c \
+crypto/cms/cms_pwri.c \
+crypto/cms/cms_sd.c \
+crypto/cms/cms_smime.c \
 crypto/comp/c_rle.c \
 crypto/comp/c_zlib.c \
 crypto/comp/comp_err.c \
@@ -800,6 +873,12 @@
 crypto/aes/aes_core.c \
 "
 
+OPENSSL_CRYPTO_SOURCES_arm64="\
+"
+
+OPENSSL_CRYPTO_SOURCES_EXCLUDES_arm64="\
+"
+
 OPENSSL_CRYPTO_SOURCES_mips="\
 crypto/aes/asm/aes-mips.S \
 crypto/bn/asm/bn-mips.S \
@@ -866,8 +945,10 @@
 OPENSSL_CRYPTO_SOURCES_EXCLUDES_x86_64="\
 crypto/aes/aes_cbc.c \
 crypto/aes/aes_core.c \
+crypto/bn/bn_asm.c \
 crypto/mem_clr.c \
 crypto/rc4/rc4_enc.c \
+crypto/rc4/rc4_skey.c \
 "
 
 OPENSSL_SSL_INCLUDES="\
@@ -938,6 +1019,7 @@
 apps/asn1pars.c \
 apps/ca.c \
 apps/ciphers.c \
+apps/cms.c \
 apps/crl.c \
 apps/crl2p7.c \
 apps/dgst.c \
@@ -993,109 +1075,8 @@
 fix_clang_build.patch \
 tls12_digests.patch \
 alpn.patch \
+cbc_record_splitting.patch \
+paddingext.patch \
 early_ccs.patch \
 0018-tls_fallback_scsv.patch \
 "
-
-OPENSSL_PATCHES_progs_SOURCES="\
-apps/openssl.c \
-apps/progs.h \
-apps/speed.c \
-crypto/ui/ui_openssl.c \
-"
-
-OPENSSL_PATCHES_handshake_cutthrough_SOURCES="\
-apps/s_client.c \
-ssl/s3_clnt.c \
-ssl/s3_lib.c \
-ssl/ssl.h \
-ssl/ssl3.h \
-ssl/ssl_lib.c \
-ssl/ssltest.c \
-test/testssl \
-"
-
-OPENSSL_PATCHES_jsse_SOURCES="\
-ssl/ssl.h \
-ssl/d1_clnt.c \
-ssl/s23_clnt.c \
-ssl/s3_both.c \
-ssl/s3_clnt.c \
-ssl/s3_srvr.c \
-ssl/ssl_ciph.c \
-ssl/ssl_err.c \
-ssl/ssl_lib.c \
-ssl/ssl_locl.h
-ssl/ssl_rsa.c \
-ssl/ssl_sess.c \
-"
-
-OPENSSL_PATCHES_channelid_SOURCES="\
-crypto/evp/evp.h \
-crypto/evp/p_lib.c \
-ssl/s3_both.c \
-ssl/s3_clnt.c \
-ssl/s3_lib.c \
-ssl/s3_srvr.c \
-ssl/ssl.h \
-ssl/ssl3.h \
-ssl/ssl_err.c \
-ssl/ssl_lib.c \
-ssl/ssl_locl.h \
-ssl/t1_lib.c \
-ssl/tls1.h \
-"
-
-OPENSSL_PATCHES_fix_clang_build_SOURCES="\
-crypto/bio/b_sock.c \
-crypto/x509v3/v3_utl.c \
-"
-
-OPENSSL_PATCHES_tls12_digests_SOURCES="\
-ssl/s3_clnt.c \
-ssl/ssl3.h \
-ssl/ssl_cert.c \
-ssl/ssl_lib.c \
-ssl/ssl_locl.h \
-ssl/t1_lib.c \
-"
-
-OPENSSL_PATCHES_alpn_SOURCES="\
-apps/s_client.c \
-ssl/s3_lib.c \
-ssl/ssl.h \
-ssl/ssl3.h \
-ssl/ssl_lib.c \
-ssl/t1_lib.c \
-ssl/tls1.h \
-"
-
-OPENSSL_PATCHES_early_ccs_SOURCES="\
-ssl/s3_clnt.c \
-ssl/s3_pkt.c \
-ssl/s3_srvr.c \
-ssl/ssl.h \
-ssl/ssl3.h \
-ssl/ssl_err.c \
-"
-
-OPENSSL_PATCHES_fallback_scsv_SOURCES="\
-crypto/err/openssl.ec \
-include/openssl/dtls1.h \
-include/openssl/ssl.h \
-include/openssl/ssl3.h \
-include/openssl/tls1.h \
-ssl/d1_lib.c \
-ssl/dtls1.h \
-ssl/s23_clnt.c \
-ssl/s23_srvr.c \
-ssl/s2_lib.c \
-ssl/s3_enc.c \
-ssl/s3_lib.c \
-ssl/ssl.h \
-ssl/ssl3.h \
-ssl/ssl_err.c \
-ssl/ssl_lib.c \
-ssl/t1_enc.c \
-ssl/tls1.h \
-"
diff --git a/openssl.version b/openssl.version
index b4e8cab..87f49ad 100644
--- a/openssl.version
+++ b/openssl.version
@@ -1 +1 @@
-OPENSSL_VERSION=1.0.1e
+OPENSSL_VERSION=1.0.1f
diff --git a/patches/README b/patches/README
index 2506ff8..c355482 100644
--- a/patches/README
+++ b/patches/README
@@ -38,6 +38,16 @@
 blessed version of NPN and we'll be supporting both ALPN and NPN for
 some time yet.
 
+cbc_record_splitting.patch
+
+BEAST attack client-side mitigation. Removes 0/n record splitting, adds 1/n-1
+record splitting. Record splitting is disabled by default.
+
+paddingext.patch
+
+ClientHello padding extension which is added, when needed, to work around bugs
+in F5 terminators.
+
 tls_fallback_scsv.patch
 
 Adds the signalling cipher suite value (SCSV) from
diff --git a/patches/cbc_record_splitting.patch b/patches/cbc_record_splitting.patch
new file mode 100644
index 0000000..37e58a1
--- /dev/null
+++ b/patches/cbc_record_splitting.patch
@@ -0,0 +1,533 @@
+From 6d65fc2d2bd6d6f4a5de364ff2cf7ec2da8f5037 Mon Sep 17 00:00:00 2001
+From: Adam Langley <agl@chromium.org>
+Date: Thu, 31 Oct 2013 13:22:54 -0400
+
+This patch removes support for empty records (which is almost
+universally disabled via SSL_OP_ALL) and adds optional support for 1/n-1
+record splitting.
+
+The latter is not enabled by default, since it's not typically used on
+servers, but it should be enabled in web browsers since there are known
+attacks in that case (see BEAST).
+
+(Of course, this is a poor workaround for using TLS 1.2 and an AEAD
+cipher suite).
+---
+ apps/s_client.c |  16 +++++---
+ ssl/d1_pkt.c    |  50 ++++---------------------
+ ssl/s3_enc.c    |  17 ++++-----
+ ssl/s3_pkt.c    | 112 +++++++++++++++++++++++++++++++-------------------------
+ ssl/ssl.h       |  19 +++++++---
+ ssl/ssl3.h      |   4 +-
+ ssl/ssl_locl.h  |   2 -
+ ssl/t1_enc.c    |  10 ++---
+ 8 files changed, 109 insertions(+), 121 deletions(-)
+
+diff --git a/apps/s_client.c b/apps/s_client.c
+index cb1efcd..0c70580 100644
+--- a/apps/s_client.c
++++ b/apps/s_client.c
+@@ -363,6 +363,7 @@ static void sc_usage(void)
+ # endif
+ #endif
+ 	BIO_printf(bio_err," -cutthrough       - enable 1-RTT full-handshake for strong ciphers\n");
++	BIO_printf(bio_err," -no_record_splitting  - disable 1/n-1 record splitting in CBC mode\n");
+ 	BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
+ #ifndef OPENSSL_NO_SRTP
+ 	BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
+@@ -579,7 +580,7 @@ int MAIN(int argc, char **argv)
+ 	EVP_PKEY *key = NULL;
+ 	char *CApath=NULL,*CAfile=NULL,*cipher=NULL;
+ 	int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0;
+-	int cutthrough=0;
++	int cutthrough=0, no_record_splitting=0;
+ 	int crlf=0;
+ 	int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending;
+ 	SSL_CTX *ctx=NULL;
+@@ -594,6 +595,7 @@ int MAIN(int argc, char **argv)
+ 	char *inrand=NULL;
+ 	int mbuf_len=0;
+ 	struct timeval timeout, *timeoutp;
++	int ssl_mode;
+ #ifndef OPENSSL_NO_ENGINE
+ 	char *engine_id=NULL;
+ 	char *ssl_client_engine_id=NULL;
+@@ -894,6 +896,8 @@ int MAIN(int argc, char **argv)
+ #endif
+ 		else if (strcmp(*argv,"-cutthrough") == 0)
+ 			cutthrough=1;
++		else if (strcmp(*argv,"-no_record_splitting") == 0)
++			no_record_splitting=1;
+ 		else if (strcmp(*argv,"-serverpref") == 0)
+ 			off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
+ 		else if (strcmp(*argv,"-legacy_renegotiation") == 0)
+@@ -1183,14 +1187,16 @@ bad:
+ 		}
+ #endif
+ 
+-	/* Enable handshake cutthrough for client connections using
+-	 * strong ciphers. */
++	ssl_mode = SSL_CTX_get_mode(ctx);
++	if (!no_record_splitting)
++		ssl_mode |= SSL_MODE_CBC_RECORD_SPLITTING;
+ 	if (cutthrough)
+ 		{
+-		int ssl_mode = SSL_CTX_get_mode(ctx);
++		/* Enable handshake cutthrough for client connections using
++		 * strong ciphers. */
+ 		ssl_mode |= SSL_MODE_HANDSHAKE_CUTTHROUGH;
+-		SSL_CTX_set_mode(ctx, ssl_mode);
+ 		}
++	SSL_CTX_set_mode(ctx, ssl_mode);
+ 
+ 	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
+ 	if (cipher != NULL)
+diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c
+index 0bf87be..cb0f8f0 100644
+--- a/ssl/d1_pkt.c
++++ b/ssl/d1_pkt.c
+@@ -179,6 +179,8 @@ static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr,
+ static int dtls1_buffer_record(SSL *s, record_pqueue *q,
+ 	unsigned char *priority);
+ static int dtls1_process_record(SSL *s);
++static int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
++			  unsigned int len);
+ 
+ /* copy buffered record into SSL structure */
+ static int
+@@ -1456,11 +1458,12 @@ int dtls1_write_bytes(SSL *s, int type, const void *buf, int len)
+ 
+ 	OPENSSL_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH);
+ 	s->rwstate=SSL_NOTHING;
+-	i=do_dtls1_write(s, type, buf, len, 0);
++	i=do_dtls1_write(s, type, buf, len);
+ 	return i;
+ 	}
+ 
+-int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, int create_empty_fragment)
++static int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
++			  unsigned int len)
+ 	{
+ 	unsigned char *p,*pseq;
+ 	int i,mac_size,clear=0;
+@@ -1487,7 +1490,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len,
+ 		/* if it went, fall through and send more stuff */
+ 		}
+ 
+-	if (len == 0 && !create_empty_fragment)
++	if (len == 0)
+ 		return 0;
+ 
+ 	wr= &(s->s3->wrec);
+@@ -1508,37 +1511,6 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len,
+ 			goto err;
+ 		}
+ 
+-	/* DTLS implements explicit IV, so no need for empty fragments */
+-#if 0
+-	/* 'create_empty_fragment' is true only when this function calls itself */
+-	if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done
+-	    && SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER)
+-		{
+-		/* countermeasure against known-IV weakness in CBC ciphersuites
+-		 * (see http://www.openssl.org/~bodo/tls-cbc.txt) 
+-		 */
+-
+-		if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA)
+-			{
+-			/* recursive function call with 'create_empty_fragment' set;
+-			 * this prepares and buffers the data for an empty fragment
+-			 * (these 'prefix_len' bytes are sent out later
+-			 * together with the actual payload) */
+-			prefix_len = s->method->do_ssl_write(s, type, buf, 0, 1);
+-			if (prefix_len <= 0)
+-				goto err;
+-
+-			if (s->s3->wbuf.len < (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE)
+-				{
+-				/* insufficient space */
+-				SSLerr(SSL_F_DO_DTLS1_WRITE, ERR_R_INTERNAL_ERROR);
+-				goto err;
+-				}
+-			}
+-		
+-		s->s3->empty_fragment_done = 1;
+-		}
+-#endif
+ 	p = wb->buf + prefix_len;
+ 
+ 	/* write the header */
+@@ -1644,14 +1616,6 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len,
+ 
+ 	ssl3_record_sequence_update(&(s->s3->write_sequence[0]));
+ 
+-	if (create_empty_fragment)
+-		{
+-		/* we are in a recursive call;
+-		 * just return the length, don't write out anything here
+-		 */
+-		return wr->length;
+-		}
+-
+ 	/* now let's set up wb */
+ 	wb->left = prefix_len + wr->length;
+ 	wb->offset = 0;
+@@ -1748,7 +1712,7 @@ int dtls1_dispatch_alert(SSL *s)
+ 		}
+ #endif
+ 
+-	i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0);
++	i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf));
+ 	if (i <= 0)
+ 		{
+ 		s->s3->alert_dispatch=1;
+diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
+index 191b86b..6358e1b 100644
+--- a/ssl/s3_enc.c
++++ b/ssl/s3_enc.c
+@@ -434,27 +434,26 @@ int ssl3_setup_key_block(SSL *s)
+ 
+ 	ret = ssl3_generate_key_block(s,p,num);
+ 
+-	if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
++	/* enable vulnerability countermeasure for CBC ciphers with
++	 * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt) */
++	if ((s->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0)
+ 		{
+-		/* enable vulnerability countermeasure for CBC ciphers with
+-		 * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt)
+-		 */
+-		s->s3->need_empty_fragments = 1;
++		s->s3->need_record_splitting = 1;
+ 
+ 		if (s->session->cipher != NULL)
+ 			{
+ 			if (s->session->cipher->algorithm_enc == SSL_eNULL)
+-				s->s3->need_empty_fragments = 0;
+-			
++				s->s3->need_record_splitting = 0;
++
+ #ifndef OPENSSL_NO_RC4
+ 			if (s->session->cipher->algorithm_enc == SSL_RC4)
+-				s->s3->need_empty_fragments = 0;
++				s->s3->need_record_splitting = 0;
+ #endif
+ 			}
+ 		}
+ 
+ 	return ret;
+-		
++
+ err:
+ 	SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);
+ 	return(0);
+diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
+index 04b474d..d690493 100644
+--- a/ssl/s3_pkt.c
++++ b/ssl/s3_pkt.c
+@@ -118,7 +118,7 @@
+ #include <openssl/rand.h>
+ 
+ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+-			 unsigned int len, int create_empty_fragment);
++			 unsigned int len, char fragment, char is_fragment);
+ static int ssl3_get_record(SSL *s);
+ 
+ int ssl3_read_n(SSL *s, int n, int max, int extend)
+@@ -618,12 +618,34 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
+ 	n=(len-tot);
+ 	for (;;)
+ 		{
+-		if (n > s->max_send_fragment)
+-			nw=s->max_send_fragment;
++		/* max contains the maximum number of bytes that we can put
++		 * into a record. */
++		unsigned max = s->max_send_fragment;
++		/* fragment is true if do_ssl3_write should send the first byte
++		 * in its own record in order to randomise a CBC IV. */
++		int fragment = 0;
++
++		if (n > 1 &&
++		    s->s3->need_record_splitting &&
++		    type == SSL3_RT_APPLICATION_DATA &&
++		    !s->s3->record_split_done)
++			{
++			fragment = 1;
++			/* The first byte will be in its own record, so we
++			 * can write an extra byte. */
++			max++;
++			/* record_split_done records that the splitting has
++			 * been done in case we hit an SSL_WANT_WRITE condition.
++			 * In that case, we don't need to do the split again. */
++			s->s3->record_split_done = 1;
++			}
++
++		if (n > max)
++			nw=max;
+ 		else
+ 			nw=n;
+ 
+-		i=do_ssl3_write(s, type, &(buf[tot]), nw, 0);
++		i=do_ssl3_write(s, type, &(buf[tot]), nw, fragment, 0);
+ 		if (i <= 0)
+ 			{
+ 			s->s3->wnum=tot;
+@@ -634,10 +656,10 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
+ 			(type == SSL3_RT_APPLICATION_DATA &&
+ 			 (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)))
+ 			{
+-			/* next chunk of data should get another prepended empty fragment
+-			 * in ciphersuites with known-IV weakness: */
+-			s->s3->empty_fragment_done = 0;
+-			
++			/* next chunk of data should get another prepended,
++			 * one-byte fragment in ciphersuites with known-IV
++			 * weakness. */
++			s->s3->record_split_done = 0;
+ 			return tot+i;
+ 			}
+ 
+@@ -646,11 +668,16 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
+ 		}
+ 	}
+ 
++/* do_ssl3_write writes an SSL record of the given type. If |fragment| is 1
++ * then it splits the record into a one byte record and a record with the rest
++ * of the data in order to randomise a CBC IV. If |is_fragment| is true then
++ * this call resulted from do_ssl3_write calling itself in order to create that
++ * one byte fragment. */
+ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+-			 unsigned int len, int create_empty_fragment)
++			 unsigned int len, char fragment, char is_fragment)
+ 	{
+ 	unsigned char *p,*plen;
+-	int i,mac_size,clear=0;
++	int i,mac_size;
+ 	int prefix_len=0;
+ 	int eivlen;
+ 	long align=0;
+@@ -676,7 +703,7 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+ 		/* if it went, fall through and send more stuff */
+ 		}
+ 
+-	if (len == 0 && !create_empty_fragment)
++	if (len == 0)
+ 		return 0;
+ 
+ 	wr= &(s->s3->wrec);
+@@ -686,11 +713,6 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+ 		(s->enc_write_ctx == NULL) ||
+ 		(EVP_MD_CTX_md(s->write_hash) == NULL))
+ 		{
+-#if 1
+-		clear=s->enc_write_ctx?0:1;	/* must be AEAD cipher */
+-#else
+-		clear=1;
+-#endif
+ 		mac_size=0;
+ 		}
+ 	else
+@@ -700,42 +722,33 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+ 			goto err;
+ 		}
+ 
+-	/* 'create_empty_fragment' is true only when this function calls itself */
+-	if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done)
++	if (fragment)
+ 		{
+ 		/* countermeasure against known-IV weakness in CBC ciphersuites
+ 		 * (see http://www.openssl.org/~bodo/tls-cbc.txt) */
++		prefix_len = do_ssl3_write(s, type, buf, 1 /* length */,
++					   0 /* fragment */,
++					   1 /* is_fragment */);
++		if (prefix_len <= 0)
++			goto err;
+ 
+-		if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA)
++		if (prefix_len > (SSL3_RT_HEADER_LENGTH +
++				  SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD))
+ 			{
+-			/* recursive function call with 'create_empty_fragment' set;
+-			 * this prepares and buffers the data for an empty fragment
+-			 * (these 'prefix_len' bytes are sent out later
+-			 * together with the actual payload) */
+-			prefix_len = do_ssl3_write(s, type, buf, 0, 1);
+-			if (prefix_len <= 0)
+-				goto err;
+-
+-			if (prefix_len >
+-		(SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD))
+-				{
+-				/* insufficient space */
+-				SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
+-				goto err;
+-				}
++			/* insufficient space */
++			SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
++			goto err;
+ 			}
+-		
+-		s->s3->empty_fragment_done = 1;
+ 		}
+ 
+-	if (create_empty_fragment)
++	if (is_fragment)
+ 		{
+ #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+-		/* extra fragment would be couple of cipher blocks,
+-		 * which would be multiple of SSL3_ALIGN_PAYLOAD, so
+-		 * if we want to align the real payload, then we can
+-		 * just pretent we simply have two headers. */
+-		align = (long)wb->buf + 2*SSL3_RT_HEADER_LENGTH;
++		/* The extra fragment would be couple of cipher blocks, and
++		 * that will be a multiple of SSL3_ALIGN_PAYLOAD. So, if we
++		 * want to align the real payload, we can just pretend that we
++		 * have two headers and a byte. */
++		align = (long)wb->buf + 2*SSL3_RT_HEADER_LENGTH + 1;
+ 		align = (-align)&(SSL3_ALIGN_PAYLOAD-1);
+ #endif
+ 		p = wb->buf + align;
+@@ -772,7 +785,7 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+ 		*(p++)=s->version&0xff;
+ 
+ 	/* field where we are to write out packet length */
+-	plen=p; 
++	plen=p;
+ 	p+=2;
+ 	/* Explicit IV length, block ciphers and TLS version 1.1 or later */
+ 	if (s->enc_write_ctx && s->version >= TLS1_1_VERSION)
+@@ -800,8 +813,8 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+ 
+ 	/* lets setup the record stuff. */
+ 	wr->data=p + eivlen;
+-	wr->length=(int)len;
+-	wr->input=(unsigned char *)buf;
++	wr->length=(int)(len - (fragment != 0));
++	wr->input=(unsigned char *)buf + (fragment != 0);
+ 
+ 	/* we now 'read' from wr->input, wr->length bytes into
+ 	 * wr->data */
+@@ -854,11 +867,10 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+ 	wr->type=type; /* not needed but helps for debugging */
+ 	wr->length+=SSL3_RT_HEADER_LENGTH;
+ 
+-	if (create_empty_fragment)
++	if (is_fragment)
+ 		{
+-		/* we are in a recursive call;
+-		 * just return the length, don't write out anything here
+-		 */
++		/* we are in a recursive call; just return the length, don't
++		 * write out anything. */
+ 		return wr->length;
+ 		}
+ 
+@@ -1514,7 +1526,7 @@ int ssl3_dispatch_alert(SSL *s)
+ 	void (*cb)(const SSL *ssl,int type,int val)=NULL;
+ 
+ 	s->s3->alert_dispatch=0;
+-	i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2, 0);
++	i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2, 0, 0);
+ 	if (i <= 0)
+ 		{
+ 		s->s3->alert_dispatch=1;
+diff --git a/ssl/ssl.h b/ssl/ssl.h
+index b289bc2..8564484 100644
+--- a/ssl/ssl.h
++++ b/ssl/ssl.h
+@@ -580,11 +580,15 @@ struct ssl_session_st
+ #define SSL_OP_TLS_D5_BUG				0x00000100L
+ #define SSL_OP_TLS_BLOCK_PADDING_BUG			0x00000200L
+ 
+-/* 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
+- * implementations cannot handle it at all, which is why we include
+- * it in SSL_OP_ALL. */
++/* SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS is vestigial. Previously it disabled the
++ * insertion of empty records in CBC mode, but the empty records were commonly
++ * misinterpreted as EOF by other TLS stacks and so this was disabled by
++ * SSL_OP_ALL.
++ *
++ * This has been replaced by 1/n-1 record splitting, which is enabled by
++ * SSL_MODE_CBC_RECORD_SPLITTING in SSL_set_mode. This involves sending a
++ * one-byte record rather than an empty record and has much better
++ * compatibility. */
+ #define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS              0x00000800L /* added in 0.9.6e */
+ 
+ /* SSL_OP_ALL: various bug workarounds that should be rather harmless.
+@@ -668,6 +672,11 @@ struct ssl_session_st
+  * and Finished.  This mode enables full-handshakes to 'complete' in
+  * one RTT. */
+ #define SSL_MODE_HANDSHAKE_CUTTHROUGH 0x00000080L
++/* When set, TLS 1.0 and SSLv3, multi-byte, CBC records will be split in two:
++ * the first record will contain a single byte and the second will contain the
++ * rest of the bytes. This effectively randomises the IV and prevents BEAST
++ * attacks. */
++#define SSL_MODE_CBC_RECORD_SPLITTING 0x00000100L
+ 
+ /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
+  * they cannot be used to clear bits. */
+diff --git a/ssl/ssl3.h b/ssl/ssl3.h
+index 6a5cdbe..65f58a7 100644
+--- a/ssl/ssl3.h
++++ b/ssl/ssl3.h
+@@ -418,8 +418,8 @@ typedef struct ssl3_state_st
+ 	unsigned char client_random[SSL3_RANDOM_SIZE];
+ 
+ 	/* flags for countermeasure against known-IV weakness */
+-	int need_empty_fragments;
+-	int empty_fragment_done;
++	int need_record_splitting;
++	int record_split_done;
+ 
+ 	/* The value of 'extra' when the buffers were initialized */
+ 	int init_extra;
+diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
+index b83d8cd..dac33e2 100644
+--- a/ssl/ssl_locl.h
++++ b/ssl/ssl_locl.h
+@@ -1091,8 +1091,6 @@ int dtls1_shutdown(SSL *s);
+ 
+ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok);
+ int dtls1_get_record(SSL *s);
+-int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
+-	unsigned int len, int create_empty_fragement);
+ int dtls1_dispatch_alert(SSL *s);
+ int dtls1_enc(SSL *s, int snd);
+ 
+diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
+index 15800af..b2686f4 100644
+--- a/ssl/t1_enc.c
++++ b/ssl/t1_enc.c
+@@ -762,22 +762,22 @@ printf("\nkey block\n");
+ { int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); }
+ #endif
+ 
+-	if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)
+-		&& s->method->version <= TLS1_VERSION)
++	if (s->method->version <= TLS1_VERSION &&
++	    (s->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0)
+ 		{
+ 		/* enable vulnerability countermeasure for CBC ciphers with
+ 		 * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt)
+ 		 */
+-		s->s3->need_empty_fragments = 1;
++		s->s3->need_record_splitting = 1;
+ 
+ 		if (s->session->cipher != NULL)
+ 			{
+ 			if (s->session->cipher->algorithm_enc == SSL_eNULL)
+-				s->s3->need_empty_fragments = 0;
++				s->s3->need_record_splitting = 0;
+ 			
+ #ifndef OPENSSL_NO_RC4
+ 			if (s->session->cipher->algorithm_enc == SSL_RC4)
+-				s->s3->need_empty_fragments = 0;
++				s->s3->need_record_splitting = 0;
+ #endif
+ 			}
+ 		}
+-- 
+1.8.4.1
+
diff --git a/patches/channelid.patch b/patches/channelid.patch
index c8ebbfa..4eb025a 100644
--- a/patches/channelid.patch
+++ b/patches/channelid.patch
@@ -697,9 +697,9 @@
 --- openssl-1.0.1e.orig/ssl/ssl3.h	2013-03-05 18:49:33.223297173 +0000
 +++ openssl-1.0.1e/ssl/ssl3.h	2013-03-05 18:49:33.413299231 +0000
 @@ -539,6 +539,17 @@ typedef struct ssl3_state_st
- 	/* Set if we saw the Next Protocol Negotiation extension from our peer. */
- 	int next_proto_neg_seen;
- #endif
+	 char is_probably_safari;
+ #endif /* !OPENSSL_NO_EC */
+ #endif /* !OPENSSL_NO_TLSEXT */
 +
 +	/* In a client, this means that the server supported Channel ID and that
 +	 * a Channel ID was sent. In a server it means that we echoed support
diff --git a/patches/handshake_cutthrough.patch b/patches/handshake_cutthrough.patch
index 7930c44..f05a10f 100644
--- a/patches/handshake_cutthrough.patch
+++ b/patches/handshake_cutthrough.patch
@@ -1,11 +1,25 @@
-commit 15a86b921a7eaa190a22a0a369e4e99beb91f5ad
-Author: Adam Langley <agl@chromium.org>
-Date:   Mon Mar 26 17:43:29 2012 -0400
+From d0e735d01271055f09bc4a1be034253e6e3c2dee Mon Sep 17 00:00:00 2001
+From: Adam Langley <agl@chromium.org>
+Date: Thu, 24 Jan 2013 16:22:07 -0500
+Subject: [PATCH] handshake_cutthrough
 
-    handshake_cutthrough
+Enables SSL3+ clients to send application data immediately following the
+Finished message even when negotiating full-handshakes.  With this
+patch, clients can negotiate SSL connections in 1-RTT even when
+performing full-handshakes.
+---
+ apps/s_client.c | 13 +++++++++++++
+ ssl/s3_clnt.c   | 53 +++++++++++++++++++++++++++++++++++++++++++++++------
+ ssl/s3_lib.c    | 15 ++++++++++++++-
+ ssl/ssl.h       |  8 +++++++-
+ ssl/ssl3.h      |  1 +
+ ssl/ssl_lib.c   | 13 +++++++++++++
+ ssl/ssltest.c   | 12 ++++++++++++
+ test/testssl    |  3 +++
+ 8 files changed, 110 insertions(+), 8 deletions(-)
 
 diff --git a/apps/s_client.c b/apps/s_client.c
-index 098cce2..0e10766 100644
+index 3ba6605..791e277 100644
 --- a/apps/s_client.c
 +++ b/apps/s_client.c
 @@ -361,6 +361,7 @@ static void sc_usage(void)
@@ -14,9 +28,9 @@
  #endif
 +	BIO_printf(bio_err," -cutthrough       - enable 1-RTT full-handshake for strong ciphers\n");
  	BIO_printf(bio_err," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
+ #ifndef OPENSSL_NO_SRTP
  	BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
-  	BIO_printf(bio_err," -keymatexport label   - Export keying material using label\n");
-@@ -573,6 +574,7 @@ int MAIN(int argc, char **argv)
+@@ -577,6 +578,7 @@ int MAIN(int argc, char **argv)
  	EVP_PKEY *key = NULL;
  	char *CApath=NULL,*CAfile=NULL,*cipher=NULL;
  	int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0;
@@ -24,7 +38,7 @@
  	int crlf=0;
  	int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending;
  	SSL_CTX *ctx=NULL;
-@@ -885,6 +887,8 @@ int MAIN(int argc, char **argv)
+@@ -883,6 +885,8 @@ int MAIN(int argc, char **argv)
  			}
  # endif
  #endif
@@ -33,7 +47,7 @@
  		else if (strcmp(*argv,"-serverpref") == 0)
  			off|=SSL_OP_CIPHER_SERVER_PREFERENCE;
  		else if (strcmp(*argv,"-legacy_renegotiation") == 0)
-@@ -1156,6 +1160,15 @@ bad:
+@@ -1158,6 +1162,15 @@ bad:
  		SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
  #endif
  
@@ -50,7 +64,7 @@
  	if (cipher != NULL)
  		if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
 diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
-index 4511a91..d2ecc3e 100644
+index 344e2eb..c3bf18a 100644
 --- a/ssl/s3_clnt.c
 +++ b/ssl/s3_clnt.c
 @@ -215,6 +215,24 @@ int ssl3_connect(SSL *s)
@@ -78,7 +92,7 @@
  	for (;;)
  		{
  		state=s->state;
-@@ -527,14 +533,31 @@ int ssl3_connect(SSL *s)
+@@ -526,14 +532,31 @@ int ssl3_connect(SSL *s)
  				}
  			else
  				{
@@ -116,7 +130,7 @@
  				}
  			s->init_num=0;
  			break;
-@@ -582,6 +605,24 @@ int ssl3_connect(SSL *s)
+@@ -581,6 +604,24 @@ int ssl3_connect(SSL *s)
  			s->state=s->s3->tmp.next_state;
  			break;
  
@@ -142,7 +156,7 @@
  			/* clean a few things up */
  			ssl3_cleanup_key_block(s);
 diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
-index db75479..a2ea25a 100644
+index e7c5dcb..0d77c40 100644
 --- a/ssl/s3_lib.c
 +++ b/ssl/s3_lib.c
 @@ -4199,9 +4199,22 @@ int ssl3_write(SSL *s, const void *buf, int len)
@@ -170,21 +184,21 @@
  	s->s3->in_read_app_data=1;
  	ret=s->method->ssl_read_bytes(s,SSL3_RT_APPLICATION_DATA,buf,len,peek);
 diff --git a/ssl/ssl.h b/ssl/ssl.h
-index 72ed766..ceaf647 100644
+index f9c9049..f2af98c 100644
 --- a/ssl/ssl.h
 +++ b/ssl/ssl.h
-@@ -638,6 +638,10 @@ 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
+@@ -649,6 +649,10 @@ struct ssl_session_st
+  */
+ #define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L
+ #define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L
 +/* When set, clients may send application data before receipt of CCS
 + * and Finished.  This mode enables full-handshakes to 'complete' in
 + * one RTT. */
-+#define SSL_MODE_HANDSHAKE_CUTTHROUGH 0x00000020L
++#define SSL_MODE_HANDSHAKE_CUTTHROUGH 0x00000080L
  
  /* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
   * they cannot be used to clear bits. */
-@@ -1410,10 +1414,12 @@ extern "C" {
+@@ -1415,10 +1419,12 @@ extern "C" {
  /* Is the SSL_connection established? */
  #define SSL_get_state(a)		SSL_state(a)
  #define SSL_is_init_finished(a)		(SSL_state(a) == SSL_ST_OK)
@@ -199,7 +213,7 @@
  /* The following 2 states are kept in ssl->rstate when reads fail,
   * you should not need these */
 diff --git a/ssl/ssl3.h b/ssl/ssl3.h
-index 112e627..556ffc1 100644
+index 247e88c..bd0d764 100644
 --- a/ssl/ssl3.h
 +++ b/ssl/ssl3.h
 @@ -547,6 +547,7 @@ typedef struct ssl3_state_st
@@ -211,10 +225,10 @@
  #define DTLS1_SCTP_ST_CW_WRITE_SOCK			(0x310|SSL_ST_CONNECT)
  #define DTLS1_SCTP_ST_CR_READ_SOCK			(0x320|SSL_ST_CONNECT)
 diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
-index f82d071..518f152 100644
+index 14d143d..a56e6ef 100644
 --- a/ssl/ssl_lib.c
 +++ b/ssl/ssl_lib.c
-@@ -3211,6 +3211,19 @@ void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int con
+@@ -3225,6 +3225,19 @@ void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int con
  	SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
  	}
  
@@ -235,7 +249,7 @@
   * vairable, freeing  EVP_MD_CTX previously stored in that variable, if
   * any. If EVP_MD pointer is passed, initializes ctx with this md
 diff --git a/ssl/ssltest.c b/ssl/ssltest.c
-index 0f8fd39..02ce4ec 100644
+index 316bbb0..91169bb 100644
 --- a/ssl/ssltest.c
 +++ b/ssl/ssltest.c
 @@ -369,6 +369,7 @@ static void sv_usage(void)
@@ -279,7 +293,7 @@
  #ifndef OPENSSL_NO_DH
  	if (!no_dhe)
 diff --git a/test/testssl b/test/testssl
-index 5ae4dc8..5dfeeeb 100644
+index 4e8542b..b5f90ba 100644
 --- a/test/testssl
 +++ b/test/testssl
 @@ -70,6 +70,9 @@ $ssltest -client_auth $CA $extra || exit 1
@@ -292,3 +306,6 @@
  echo test sslv2 via BIO pair
  $ssltest -bio_pair -ssl2 $extra || exit 1
  
+-- 
+1.8.2.1
+
diff --git a/patches/paddingext.patch b/patches/paddingext.patch
new file mode 100644
index 0000000..37514bc
--- /dev/null
+++ b/patches/paddingext.patch
@@ -0,0 +1,99 @@
+From 9336ed61c26255f31fac2563d0911fc29d2143fd Mon Sep 17 00:00:00 2001
+From: Adam Langley <agl@chromium.org>
+Date: Wed, 11 Dec 2013 16:25:17 -0500
+Subject: Add padding extension.
+
+This change adds a padding extension, when needed, in order to work
+around bugs in F5 terminators.
+---
+ ssl/s23_clnt.c |  5 ++++-
+ ssl/s3_clnt.c  |  4 +++-
+ ssl/t1_lib.c   | 25 +++++++++++++++++++++++++
+ ssl/tls1.h     |  4 ++++
+ 4 files changed, 36 insertions(+), 2 deletions(-)
+
+diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c
+index 84670b6..814a4c6 100644
+--- a/ssl/s23_clnt.c
++++ b/ssl/s23_clnt.c
+@@ -487,7 +487,10 @@ static int ssl23_client_hello(SSL *s)
+ 			{
+ 			/* create Client Hello in SSL 3.0/TLS 1.0 format */
+ 
+-			/* do the record header (5 bytes) and handshake message header (4 bytes) last */
++			/* do the record header (5 bytes) and handshake message
++			 * header (4 bytes) last. Note: the code to add the
++			 * padding extension in t1_lib.c depends on the size of
++			 * this prefix. */
+ 			d = p = &(buf[9]);
+ 			
+ 			*(p++) = version_major;
+diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
+index 67edeaa..f37e907 100644
+--- a/ssl/s3_clnt.c
++++ b/ssl/s3_clnt.c
+@@ -751,7 +751,9 @@ int ssl3_client_hello(SSL *s)
+ 		if (ssl_fill_hello_random(s, 0, p, SSL3_RANDOM_SIZE) <= 0)
+ 			goto err;
+ 
+-		/* Do the message type and length last */
++		/* Do the message type and length last.
++		 * Note: the code to add the padding extension in t1_lib.c
++		 * depends on the size of this prefix. */
+ 		d=p= &(buf[4]);
+ 
+ 		/* version indicates the negotiated version: for example from
+diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
+index 357db6e..a499367 100644
+--- a/ssl/t1_lib.c
++++ b/ssl/t1_lib.c
+@@ -687,6 +687,31 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
+                 }
+ #endif
+ 
++	/* Add padding to workaround bugs in F5 terminators.
++	 * See https://tools.ietf.org/html/draft-agl-tls-padding-02 */
++	{
++	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;
++		}
++	}
++
++
+ 	if ((extdatalen = ret-p-2)== 0) 
+ 		return p;
+ 
+diff --git a/ssl/tls1.h b/ssl/tls1.h
+index ecf5da7..df8f482 100644
+--- a/ssl/tls1.h
++++ b/ssl/tls1.h
+@@ -255,6 +255,10 @@ extern "C" {
+ #define TLSEXT_TYPE_channel_id			30031
+ #define TLSEXT_TYPE_channel_id_new		30032
+ 
++/* See https://tools.ietf.org/html/draft-agl-tls-padding-02
++ * Number not yet IANA assigned. */
++#define TLSEXT_TYPE_padding			35655
++
+ /* NameType value from RFC 3546 */
+ #define TLSEXT_NAMETYPE_host_name 0
+ /* status request value from RFC 3546 */
+-- 
+1.8.5.1
+
diff --git a/ssl/d1_both.c b/ssl/d1_both.c
index de8bab8..7a5596a 100644
--- a/ssl/d1_both.c
+++ b/ssl/d1_both.c
@@ -214,6 +214,12 @@
 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 @@
 				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, 
diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c
index 7e8077e..4fc4e1b 100644
--- a/ssl/d1_clnt.c
+++ b/ssl/d1_clnt.c
@@ -538,13 +538,6 @@
 				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 @@
 				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 @@
 				}
 			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 @@
 	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;
@@ -804,13 +814,11 @@
 
 		/* 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/ssl/d1_lib.c b/ssl/d1_lib.c
index 43d3d9e..e27828f 100644
--- a/ssl/d1_lib.c
+++ b/ssl/d1_lib.c
@@ -196,6 +196,7 @@
 	pqueue_free(s->d1->buffered_app_data.q);
 
 	OPENSSL_free(s->d1);
+	s->d1 = NULL;
 	}
 
 void dtls1_clear(SSL *s)
diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c
index 0bf87be..5b84e97 100644
--- a/ssl/d1_pkt.c
+++ b/ssl/d1_pkt.c
@@ -179,6 +179,8 @@
 static int dtls1_buffer_record(SSL *s, record_pqueue *q,
 	unsigned char *priority);
 static int dtls1_process_record(SSL *s);
+static int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
+			  unsigned int len);
 
 /* copy buffered record into SSL structure */
 static int
@@ -847,6 +849,12 @@
 			}
 		}
 
+	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,
@@ -1051,6 +1059,7 @@
 			!(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))
@@ -1456,11 +1465,12 @@
 
 	OPENSSL_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH);
 	s->rwstate=SSL_NOTHING;
-	i=do_dtls1_write(s, type, buf, len, 0);
+	i=do_dtls1_write(s, type, buf, len);
 	return i;
 	}
 
-int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, int create_empty_fragment)
+static int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
+			  unsigned int len)
 	{
 	unsigned char *p,*pseq;
 	int i,mac_size,clear=0;
@@ -1487,7 +1497,7 @@
 		/* if it went, fall through and send more stuff */
 		}
 
-	if (len == 0 && !create_empty_fragment)
+	if (len == 0)
 		return 0;
 
 	wr= &(s->s3->wrec);
@@ -1508,37 +1518,6 @@
 			goto err;
 		}
 
-	/* DTLS implements explicit IV, so no need for empty fragments */
-#if 0
-	/* 'create_empty_fragment' is true only when this function calls itself */
-	if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done
-	    && SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER)
-		{
-		/* countermeasure against known-IV weakness in CBC ciphersuites
-		 * (see http://www.openssl.org/~bodo/tls-cbc.txt) 
-		 */
-
-		if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA)
-			{
-			/* recursive function call with 'create_empty_fragment' set;
-			 * this prepares and buffers the data for an empty fragment
-			 * (these 'prefix_len' bytes are sent out later
-			 * together with the actual payload) */
-			prefix_len = s->method->do_ssl_write(s, type, buf, 0, 1);
-			if (prefix_len <= 0)
-				goto err;
-
-			if (s->s3->wbuf.len < (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE)
-				{
-				/* insufficient space */
-				SSLerr(SSL_F_DO_DTLS1_WRITE, ERR_R_INTERNAL_ERROR);
-				goto err;
-				}
-			}
-		
-		s->s3->empty_fragment_done = 1;
-		}
-#endif
 	p = wb->buf + prefix_len;
 
 	/* write the header */
@@ -1644,14 +1623,6 @@
 
 	ssl3_record_sequence_update(&(s->s3->write_sequence[0]));
 
-	if (create_empty_fragment)
-		{
-		/* we are in a recursive call;
-		 * just return the length, don't write out anything here
-		 */
-		return wr->length;
-		}
-
 	/* now let's set up wb */
 	wb->left = prefix_len + wr->length;
 	wb->offset = 0;
@@ -1748,7 +1719,7 @@
 		}
 #endif
 
-	i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0);
+	i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf));
 	if (i <= 0)
 		{
 		s->s3->alert_dispatch=1;
diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c
index 29421da..9975e20 100644
--- a/ssl/d1_srvr.c
+++ b/ssl/d1_srvr.c
@@ -276,10 +276,11 @@
 		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 @@
 			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 @@
 			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 @@
 	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/ssl/s23_clnt.c b/ssl/s23_clnt.c
index ef20206..b43088e 100644
--- a/ssl/s23_clnt.c
+++ b/ssl/s23_clnt.c
@@ -269,12 +269,35 @@
 	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 = 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 @@
 #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)
@@ -466,7 +487,10 @@
 			{
 			/* create Client Hello in SSL 3.0/TLS 1.0 format */
 
-			/* do the record header (5 bytes) and handshake message header (4 bytes) last */
+			/* do the record header (5 bytes) and handshake message
+			 * header (4 bytes) last. Note: the code to add the
+			 * padding extension in t1_lib.c depends on the size of
+			 * this prefix. */
 			d = p = &(buf[9]);
 			
 			*(p++) = version_major;
diff --git a/ssl/s3_both.c b/ssl/s3_both.c
index 1edef20..d9e18a3 100644
--- a/ssl/s3_both.c
+++ b/ssl/s3_both.c
@@ -161,6 +161,8 @@
 
 		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;
@@ -208,7 +210,11 @@
 	{
 	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;
diff --git a/ssl/s3_cbc.c b/ssl/s3_cbc.c
index 02edf3f..443a31e 100644
--- a/ssl/s3_cbc.c
+++ b/ssl/s3_cbc.c
@@ -148,7 +148,7 @@
 	unsigned padding_length, good, to_check, i;
 	const unsigned overhead = 1 /* padding length byte */ + mac_size;
 	/* Check if version requires explicit IV */
-	if (s->version >= TLS1_1_VERSION || s->version == DTLS1_VERSION)
+	if (s->version >= TLS1_1_VERSION || s->version == DTLS1_BAD_VER)
 		{
 		/* These lengths are all public so we can test them in
 		 * non-constant time.
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index edfcf58..9979b7d 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -721,7 +721,7 @@
 	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;
@@ -752,12 +752,13 @@
 		/* 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 */
+		/* Do the message type and length last.
+		 * Note: the code to add the padding extension in t1_lib.c
+		 * depends on the size of this prefix. */
 		d=p= &(buf[4]);
 
 		/* version indicates the negotiated version: for example from
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
index 5cd3be3..1b5cc79 100644
--- a/ssl/s3_enc.c
+++ b/ssl/s3_enc.c
@@ -428,27 +428,26 @@
 
 	ret = ssl3_generate_key_block(s,p,num);
 
-	if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
+	/* enable vulnerability countermeasure for CBC ciphers with
+	 * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt) */
+	if ((s->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0)
 		{
-		/* enable vulnerability countermeasure for CBC ciphers with
-		 * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt)
-		 */
-		s->s3->need_empty_fragments = 1;
+		s->s3->need_record_splitting = 1;
 
 		if (s->session->cipher != NULL)
 			{
 			if (s->session->cipher->algorithm_enc == SSL_eNULL)
-				s->s3->need_empty_fragments = 0;
-			
+				s->s3->need_record_splitting = 0;
+
 #ifndef OPENSSL_NO_RC4
 			if (s->session->cipher->algorithm_enc == SSL_RC4)
-				s->s3->need_empty_fragments = 0;
+				s->s3->need_record_splitting = 0;
 #endif
 			}
 		}
 
 	return ret;
-		
+
 err:
 	SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);
 	return(0);
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index d88140b..f33ada3 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -1683,7 +1683,7 @@
 	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 @@
 	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 @@
 	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,
@@ -3047,6 +3047,11 @@
 		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;
@@ -4113,6 +4118,13 @@
 		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;
 			}
@@ -4384,7 +4396,7 @@
 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/ssl/s3_pkt.c b/ssl/s3_pkt.c
index 8f0daf3..75997ac 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -118,7 +118,7 @@
 #include <openssl/rand.h>
 
 static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
-			 unsigned int len, int create_empty_fragment);
+			 unsigned int len, char fragment, char is_fragment);
 static int ssl3_get_record(SSL *s);
 
 int ssl3_read_n(SSL *s, int n, int max, int extend)
@@ -335,7 +335,7 @@
 			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;
@@ -601,12 +601,34 @@
 	n=(len-tot);
 	for (;;)
 		{
-		if (n > s->max_send_fragment)
-			nw=s->max_send_fragment;
+		/* max contains the maximum number of bytes that we can put
+		 * into a record. */
+		unsigned max = s->max_send_fragment;
+		/* fragment is true if do_ssl3_write should send the first byte
+		 * in its own record in order to randomise a CBC IV. */
+		int fragment = 0;
+
+		if (n > 1 &&
+		    s->s3->need_record_splitting &&
+		    type == SSL3_RT_APPLICATION_DATA &&
+		    !s->s3->record_split_done)
+			{
+			fragment = 1;
+			/* The first byte will be in its own record, so we
+			 * can write an extra byte. */
+			max++;
+			/* record_split_done records that the splitting has
+			 * been done in case we hit an SSL_WANT_WRITE condition.
+			 * In that case, we don't need to do the split again. */
+			s->s3->record_split_done = 1;
+			}
+
+		if (n > max)
+			nw=max;
 		else
 			nw=n;
 
-		i=do_ssl3_write(s, type, &(buf[tot]), nw, 0);
+		i=do_ssl3_write(s, type, &(buf[tot]), nw, fragment, 0);
 		if (i <= 0)
 			{
 			s->s3->wnum=tot;
@@ -617,10 +639,10 @@
 			(type == SSL3_RT_APPLICATION_DATA &&
 			 (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)))
 			{
-			/* next chunk of data should get another prepended empty fragment
-			 * in ciphersuites with known-IV weakness: */
-			s->s3->empty_fragment_done = 0;
-			
+			/* next chunk of data should get another prepended,
+			 * one-byte fragment in ciphersuites with known-IV
+			 * weakness. */
+			s->s3->record_split_done = 0;
 			return tot+i;
 			}
 
@@ -629,11 +651,16 @@
 		}
 	}
 
+/* do_ssl3_write writes an SSL record of the given type. If |fragment| is 1
+ * then it splits the record into a one byte record and a record with the rest
+ * of the data in order to randomise a CBC IV. If |is_fragment| is true then
+ * this call resulted from do_ssl3_write calling itself in order to create that
+ * one byte fragment. */
 static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
-			 unsigned int len, int create_empty_fragment)
+			 unsigned int len, char fragment, char is_fragment)
 	{
 	unsigned char *p,*plen;
-	int i,mac_size,clear=0;
+	int i,mac_size;
 	int prefix_len=0;
 	int eivlen;
 	long align=0;
@@ -659,7 +686,7 @@
 		/* if it went, fall through and send more stuff */
 		}
 
-	if (len == 0 && !create_empty_fragment)
+	if (len == 0)
 		return 0;
 
 	wr= &(s->s3->wrec);
@@ -669,11 +696,6 @@
 		(s->enc_write_ctx == NULL) ||
 		(EVP_MD_CTX_md(s->write_hash) == NULL))
 		{
-#if 1
-		clear=s->enc_write_ctx?0:1;	/* must be AEAD cipher */
-#else
-		clear=1;
-#endif
 		mac_size=0;
 		}
 	else
@@ -683,42 +705,33 @@
 			goto err;
 		}
 
-	/* 'create_empty_fragment' is true only when this function calls itself */
-	if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done)
+	if (fragment)
 		{
 		/* countermeasure against known-IV weakness in CBC ciphersuites
 		 * (see http://www.openssl.org/~bodo/tls-cbc.txt) */
+		prefix_len = do_ssl3_write(s, type, buf, 1 /* length */,
+					   0 /* fragment */,
+					   1 /* is_fragment */);
+		if (prefix_len <= 0)
+			goto err;
 
-		if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA)
+		if (prefix_len > (SSL3_RT_HEADER_LENGTH +
+				  SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD))
 			{
-			/* recursive function call with 'create_empty_fragment' set;
-			 * this prepares and buffers the data for an empty fragment
-			 * (these 'prefix_len' bytes are sent out later
-			 * together with the actual payload) */
-			prefix_len = do_ssl3_write(s, type, buf, 0, 1);
-			if (prefix_len <= 0)
-				goto err;
-
-			if (prefix_len >
-		(SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD))
-				{
-				/* insufficient space */
-				SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
-				goto err;
-				}
+			/* insufficient space */
+			SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
+			goto err;
 			}
-		
-		s->s3->empty_fragment_done = 1;
 		}
 
-	if (create_empty_fragment)
+	if (is_fragment)
 		{
 #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
-		/* extra fragment would be couple of cipher blocks,
-		 * which would be multiple of SSL3_ALIGN_PAYLOAD, so
-		 * if we want to align the real payload, then we can
-		 * just pretent we simply have two headers. */
-		align = (long)wb->buf + 2*SSL3_RT_HEADER_LENGTH;
+		/* The extra fragment would be couple of cipher blocks, and
+		 * that will be a multiple of SSL3_ALIGN_PAYLOAD. So, if we
+		 * want to align the real payload, we can just pretend that we
+		 * have two headers and a byte. */
+		align = (long)wb->buf + 2*SSL3_RT_HEADER_LENGTH + 1;
 		align = (-align)&(SSL3_ALIGN_PAYLOAD-1);
 #endif
 		p = wb->buf + align;
@@ -755,7 +768,7 @@
 		*(p++)=s->version&0xff;
 
 	/* field where we are to write out packet length */
-	plen=p; 
+	plen=p;
 	p+=2;
 	/* Explicit IV length, block ciphers and TLS version 1.1 or later */
 	if (s->enc_write_ctx && s->version >= TLS1_1_VERSION)
@@ -778,8 +791,8 @@
 
 	/* lets setup the record stuff. */
 	wr->data=p + eivlen;
-	wr->length=(int)len;
-	wr->input=(unsigned char *)buf;
+	wr->length=(int)(len - (fragment != 0));
+	wr->input=(unsigned char *)buf + (fragment != 0);
 
 	/* we now 'read' from wr->input, wr->length bytes into
 	 * wr->data */
@@ -832,11 +845,10 @@
 	wr->type=type; /* not needed but helps for debugging */
 	wr->length+=SSL3_RT_HEADER_LENGTH;
 
-	if (create_empty_fragment)
+	if (is_fragment)
 		{
-		/* we are in a recursive call;
-		 * just return the length, don't write out anything here
-		 */
+		/* we are in a recursive call; just return the length, don't
+		 * write out anything. */
 		return wr->length;
 		}
 
@@ -1471,8 +1483,14 @@
 		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);
 	}
@@ -1504,7 +1522,7 @@
 	void (*cb)(const SSL *ssl,int type,int val)=NULL;
 
 	s->s3->alert_dispatch=0;
-	i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2, 0);
+	i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2, 0, 0);
 	if (i <= 0)
 		{
 		s->s3->alert_dispatch=1;
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index 8a18833..9fdb5fd 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -972,7 +972,8 @@
 	    (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;
@@ -1219,12 +1220,9 @@
 	 * 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;
@@ -1461,19 +1459,13 @@
 	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 */
diff --git a/ssl/ssl.h b/ssl/ssl.h
index 89d5267..e2e97f1 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -555,16 +555,23 @@
 #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
 
-/* 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
- * implementations cannot handle it at all, which is why we include
- * it in SSL_OP_ALL. */
+/* Hasn't done anything since OpenSSL 0.9.7h, retained for compatibility */
+#define SSL_OP_MSIE_SSLV2_RSA_PADDING			0x0
+
+/* SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS is vestigial. Previously it disabled the
+ * insertion of empty records in CBC mode, but the empty records were commonly
+ * misinterpreted as EOF by other TLS stacks and so this was disabled by
+ * SSL_OP_ALL.
+ *
+ * This has been replaced by 1/n-1 record splitting, which is enabled by
+ * SSL_MODE_CBC_RECORD_SPLITTING in SSL_set_mode. This involves sending a
+ * one-byte record rather than an empty record and has much better
+ * compatibility. */
 #define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS              0x00000800L /* added in 0.9.6e */
 
 /* SSL_OP_ALL: various bug workarounds that should be rather harmless.
@@ -641,10 +648,21 @@
  * 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
 /* When set, clients may send application data before receipt of CCS
  * and Finished.  This mode enables full-handshakes to 'complete' in
  * one RTT. */
-#define SSL_MODE_HANDSHAKE_CUTTHROUGH 0x00000020L
+#define SSL_MODE_HANDSHAKE_CUTTHROUGH 0x00000080L
+/* When set, TLS 1.0 and SSLv3, multi-byte, CBC records will be split in two:
+ * the first record will contain a single byte and the second will contain the
+ * rest of the bytes. This effectively randomises the IV and prevents BEAST
+ * attacks. */
+#define SSL_MODE_CBC_RECORD_SPLITTING 0x00000100L
 
 /* Send TLS_FALLBACK_SCSV in the ClientHello.
  * To be set by applications that reconnect with a downgraded protocol
diff --git a/ssl/ssl3.h b/ssl/ssl3.h
index 555e1e9..1aa4023 100644
--- a/ssl/ssl3.h
+++ b/ssl/ssl3.h
@@ -427,8 +427,8 @@
 	unsigned char client_random[SSL3_RANDOM_SIZE];
 
 	/* flags for countermeasure against known-IV weakness */
-	int need_empty_fragments;
-	int empty_fragment_done;
+	int need_record_splitting;
+	int record_split_done;
 
 	/* The value of 'extra' when the buffers were initialized */
 	int init_extra;
@@ -549,6 +549,15 @@
 	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 */
+
 	/* In a client, this means that the server supported Channel ID and that
 	 * a Channel ID was sent. In a server it means that we echoed support
 	 * for Channel IDs and that tlsext_channel_id will be valid after the
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 1ce200e..c6e79dc 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1941,7 +1941,9 @@
 	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;
 
@@ -2975,9 +2977,7 @@
 /* Fix this function so that it takes an optional type parameter */
 X509 *SSL_get_certificate(const SSL *s)
 	{
-	if (s->server)
-		return(ssl_get_server_send_cert(s));
-	else if (s->cert != NULL)
+	if (s->cert != NULL)
 		return(s->cert->key->x509);
 	else
 		return(NULL);
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 917c9f3..f79ab00 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -621,6 +621,8 @@
 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)  \
@@ -847,6 +849,7 @@
 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);
@@ -1058,8 +1061,6 @@
 
 long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok);
 int dtls1_get_record(SSL *s);
-int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
-	unsigned int len, int create_empty_fragement);
 int dtls1_dispatch_alert(SSL *s);
 int dtls1_enc(SSL *s, int snd);
 
diff --git a/ssl/ssltest.c b/ssl/ssltest.c
index 91169bb..28fa223 100644
--- a/ssl/ssltest.c
+++ b/ssl/ssltest.c
@@ -887,7 +887,13 @@
 		meth=SSLv23_method();
 #else
 #ifdef OPENSSL_NO_SSL2
-	meth=SSLv3_method();
+	if (tls1)
+		meth=TLSv1_method();
+	else
+	if (ssl3)
+		meth=SSLv3_method();
+	else
+		meth=SSLv23_method();
 #else
 	meth=SSLv2_method();
 #endif
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 1cb86f4..5c9f261 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -414,15 +414,20 @@
 			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)
 			{
@@ -637,22 +642,22 @@
 { int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); }
 #endif
 
-	if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)
-		&& s->method->version <= TLS1_VERSION)
+	if (s->method->version <= TLS1_VERSION &&
+	    (s->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0)
 		{
 		/* enable vulnerability countermeasure for CBC ciphers with
 		 * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt)
 		 */
-		s->s3->need_empty_fragments = 1;
+		s->s3->need_record_splitting = 1;
 
 		if (s->session->cipher != NULL)
 			{
 			if (s->session->cipher->algorithm_enc == SSL_eNULL)
-				s->s3->need_empty_fragments = 0;
+				s->s3->need_record_splitting = 0;
 			
 #ifndef OPENSSL_NO_RC4
 			if (s->session->cipher->algorithm_enc == SSL_RC4)
-				s->s3->need_empty_fragments = 0;
+				s->s3->need_record_splitting = 0;
 #endif
 			}
 		}
@@ -915,18 +920,19 @@
 		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;
 				}
 			}
 		}
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index f170056..eba732f 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -342,19 +342,11 @@
 #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;
@@ -692,6 +684,31 @@
                 }
 #endif
 
+	/* Add padding to workaround bugs in F5 terminators.
+	 * See https://tools.ietf.org/html/draft-agl-tls-padding-02 */
+	{
+	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;
+		}
+	}
+
+
 	if ((extdatalen = ret-p-2)== 0) 
 		return p;
 
@@ -913,6 +930,89 @@
 	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 */
+
 /* tls1_alpn_handle_client_hello is called to process the ALPN extension in a
  * ClientHello.
  *   data: the contents of the extension, not including the type and length.
@@ -1016,6 +1116,11 @@
 	                       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);
@@ -2548,14 +2653,6 @@
 	{
 	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();
diff --git a/ssl/tls1.h b/ssl/tls1.h
index f798556..86507d7 100644
--- a/ssl/tls1.h
+++ b/ssl/tls1.h
@@ -257,6 +257,10 @@
 /* This is not an IANA defined extension number */
 #define TLSEXT_TYPE_channel_id			30031
 
+/* See https://tools.ietf.org/html/draft-agl-tls-padding-02
+ * Number not yet IANA assigned. */
+#define TLSEXT_TYPE_padding			35655
+
 /* NameType value from RFC 3546 */
 #define TLSEXT_NAMETYPE_host_name 0
 /* status request value from RFC 3546 */