Upgrade to openssl-0.9.8k.
The source tree (and the size of the compiled library)
can be reduced further.  This will be done in a future
commit.
diff --git a/crypto/Android.mk b/crypto/Android.mk
index 150066b..e92f0d1 100644
--- a/crypto/Android.mk
+++ b/crypto/Android.mk
@@ -133,6 +133,7 @@
 	bn/bn_ctx.c \
 	bn/bn_mul.c \
 	bn/bn_mod.c \
+	bn/bn_opt.c \
 	bn/bn_print.c \
 	bn/bn_rand.c \
 	bn/bn_shift.c \
@@ -151,8 +152,10 @@
 	bn/bn_exp2.c \
 	bn/bn_nist.c \
 	bn/bn_gf2m.c \
+	bn/bn_x931p.c \
 	buffer/buffer.c \
 	buffer/buf_err.c \
+	buffer/buf_str.c \
 	comp/comp_lib.c \
 	comp/comp_err.c \
 	comp/c_rle.c \
@@ -168,6 +171,7 @@
 	des/cbc_enc.c \
 	des/cfb64enc.c \
 	des/cfb_enc.c \
+	des/des_lib.c \
 	des/ecb3_enc.c \
 	des/ecb_enc.c \
 	des/enc_read.c \
@@ -199,10 +203,15 @@
 	dso/dso_win32.c \
 	dso/dso_vms.c \
 	err/err.c \
+	err/err_bio.c \
+	err/err_def.c \
 	err/err_all.c \
 	err/err_prn.c \
+	err/err_str.c \
 	evp/encode.c \
 	evp/digest.c \
+	evp/enc_min.c \
+	evp/evp_cnf.c \
 	evp/evp_enc.c \
 	evp/evp_key.c \
 	evp/evp_acnf.c \
@@ -303,7 +312,9 @@
 	rc2/rc2ofb64.c \
 	rc4/rc4_skey.c \
 	rc4/rc4_enc.c \
+	rsa/rsa_x931g.c \
 	rsa/rsa_eay.c \
+	rsa/rsa_eng.c \
 	rsa/rsa_gen.c \
 	rsa/rsa_lib.c \
 	rsa/rsa_sign.c \
@@ -403,6 +414,7 @@
 	dsa/dsa_lib.c \
 	dsa/dsa_ossl.c \
 	dsa/dsa_sign.c \
+	dsa/dsa_utl.c \
 	dsa/dsa_vrf.c \
 	ripemd/rmd_dgst.c \
 	ripemd/rmd_one.c \
diff --git a/crypto/Makefile b/crypto/Makefile
index bb8eaa0..6557f2b 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -33,8 +33,8 @@
 
 LIB= $(TOP)/libcrypto.a
 SHARED_LIB= libcrypto$(SHLIB_EXT)
-LIBSRC=	cryptlib.c mem.c mem_clr.c mem_dbg.c cversion.c ex_data.c tmdiff.c cpt_err.c ebcdic.c uid.c o_time.c o_str.c o_dir.c
-LIBOBJ= cryptlib.o mem.o mem_clr.o mem_dbg.o cversion.o ex_data.o tmdiff.o cpt_err.o ebcdic.o uid.o o_time.o o_str.o o_dir.o $(CPUID_OBJ)
+LIBSRC=	cryptlib.c dyn_lck.c mem.c mem_clr.c mem_dbg.c cversion.c ex_data.c tmdiff.c cpt_err.c ebcdic.c uid.c o_time.c o_str.c o_dir.c o_init.c fips_err.c
+LIBOBJ= cryptlib.o dyn_lck.o mem.o mem_clr.o mem_dbg.o cversion.o ex_data.o tmdiff.o cpt_err.o ebcdic.o uid.o o_time.o o_str.o o_dir.o o_init.o fips_err.o $(CPUID_OBJ)
 
 SRC= $(LIBSRC)
 
@@ -47,7 +47,7 @@
 top:
 	@(cd ..; $(MAKE) DIRS=$(DIR) all)
 
-all: shared
+all: lib
 
 buildinf.h: ../Makefile
 	( echo "#ifndef MK1MF_BUILD"; \
@@ -95,10 +95,10 @@
 	@target=links; $(RECURSIVE_MAKE)
 
 # lib: and $(LIB): are splitted to avoid end-less loop
-lib:	$(LIB)
+lib:	buildinf.h $(LIB) subdirs
 	@touch lib
 $(LIB):	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 
 shared: buildinf.h lib subdirs
@@ -159,6 +159,13 @@
 cversion.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
 cversion.o: ../include/openssl/stack.h ../include/openssl/symhacks.h buildinf.h
 cversion.o: cryptlib.h cversion.c
+dyn_lck.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
+dyn_lck.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
+dyn_lck.o: ../include/openssl/err.h ../include/openssl/lhash.h
+dyn_lck.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+dyn_lck.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+dyn_lck.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h
+dyn_lck.o: dyn_lck.c
 ebcdic.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h ebcdic.c
 ex_data.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
 ex_data.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
@@ -167,6 +174,13 @@
 ex_data.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
 ex_data.o: ../include/openssl/stack.h ../include/openssl/symhacks.h cryptlib.h
 ex_data.o: ex_data.c
+fips_err.o: ../include/openssl/bio.h ../include/openssl/crypto.h
+fips_err.o: ../include/openssl/e_os2.h ../include/openssl/err.h
+fips_err.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+fips_err.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+fips_err.o: ../include/openssl/ossl_typ.h ../include/openssl/safestack.h
+fips_err.o: ../include/openssl/stack.h ../include/openssl/symhacks.h fips_err.c
+fips_err.o: fips_err.h
 mem.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/buffer.h
 mem.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
 mem.o: ../include/openssl/err.h ../include/openssl/lhash.h
@@ -187,6 +201,12 @@
 mem_dbg.o: mem_dbg.c
 o_dir.o: ../e_os.h ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
 o_dir.o: LPdir_unix.c o_dir.c o_dir.h
+o_init.o: ../e_os.h ../include/openssl/bio.h ../include/openssl/crypto.h
+o_init.o: ../include/openssl/e_os2.h ../include/openssl/err.h
+o_init.o: ../include/openssl/lhash.h ../include/openssl/opensslconf.h
+o_init.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+o_init.o: ../include/openssl/safestack.h ../include/openssl/stack.h
+o_init.o: ../include/openssl/symhacks.h o_init.c
 o_str.o: ../e_os.h ../include/openssl/e_os2.h ../include/openssl/opensslconf.h
 o_str.o: o_str.c o_str.h
 o_time.o: ../include/openssl/e_os2.h ../include/openssl/opensslconf.h o_time.c
diff --git a/crypto/aes/Makefile b/crypto/aes/Makefile
index 22c7203..9d174f4 100644
--- a/crypto/aes/Makefile
+++ b/crypto/aes/Makefile
@@ -41,7 +41,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -103,7 +103,8 @@
 aes_cfb.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
 aes_cfb.o: aes_cfb.c aes_locl.h
 aes_core.o: ../../include/openssl/aes.h ../../include/openssl/e_os2.h
-aes_core.o: ../../include/openssl/opensslconf.h aes_core.c aes_locl.h
+aes_core.o: ../../include/openssl/fips.h ../../include/openssl/opensslconf.h
+aes_core.o: aes_core.c aes_locl.h
 aes_ctr.o: ../../include/openssl/aes.h ../../include/openssl/e_os2.h
 aes_ctr.o: ../../include/openssl/opensslconf.h aes_ctr.c aes_locl.h
 aes_ecb.o: ../../include/openssl/aes.h ../../include/openssl/e_os2.h
diff --git a/crypto/aes/aes.h b/crypto/aes/aes.h
index baf0222..450f2b4 100644
--- a/crypto/aes/aes.h
+++ b/crypto/aes/aes.h
@@ -66,6 +66,10 @@
 #define AES_MAXNR 14
 #define AES_BLOCK_SIZE 16
 
+#ifdef OPENSSL_FIPS
+#define FIPS_AES_SIZE_T	int
+#endif
+
 #ifdef  __cplusplus
 extern "C" {
 #endif
diff --git a/crypto/aes/aes_cbc.c b/crypto/aes/aes_cbc.c
index d2ba6bc..373864c 100644
--- a/crypto/aes/aes_cbc.c
+++ b/crypto/aes/aes_cbc.c
@@ -59,6 +59,7 @@
 #include <openssl/aes.h>
 #include "aes_locl.h"
 
+#if !defined(OPENSSL_FIPS_AES_ASM)
 void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
 		     const unsigned long length, const AES_KEY *key,
 		     unsigned char *ivec, const int enc) {
@@ -129,3 +130,4 @@
 		}
 	}
 }
+#endif
diff --git a/crypto/aes/aes_core.c b/crypto/aes/aes_core.c
index 3a80e18..cffdd4d 100644
--- a/crypto/aes/aes_core.c
+++ b/crypto/aes/aes_core.c
@@ -37,6 +37,10 @@
 
 #include <stdlib.h>
 #include <openssl/aes.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 #include "aes_locl.h"
 
 /*
@@ -631,6 +635,10 @@
    	int i = 0;
 	u32 temp;
 
+#ifdef OPENSSL_FIPS
+	FIPS_selftest_check();
+#endif
+
 	if (!userKey || !key)
 		return -1;
 	if (bits != 128 && bits != 192 && bits != 256)
diff --git a/crypto/aes/aes_x86core.c b/crypto/aes/aes_x86core.c
new file mode 100644
index 0000000..d323e26
--- /dev/null
+++ b/crypto/aes/aes_x86core.c
@@ -0,0 +1,1063 @@
+/* crypto/aes/aes_core.c -*- mode:C; c-file-style: "eay" -*- */
+/**
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This is experimental x86[_64] derivative. It assumes little-endian
+ * byte order and expects CPU to sustain unaligned memory references.
+ * It is used as playground for cache-time attack mitigations and
+ * serves as reference C implementation for x86[_64] assembler.
+ *
+ *					<appro@fy.chalmers.se>
+ */
+
+
+#ifndef AES_DEBUG
+# ifndef NDEBUG
+#  define NDEBUG
+# endif
+#endif
+#include <assert.h>
+
+#include <stdlib.h>
+#include <openssl/aes.h>
+#include "aes_locl.h"
+
+/*
+ * These two parameters control which table, 256-byte or 2KB, is
+ * referenced in outer and respectively inner rounds.
+ */
+#define AES_COMPACT_IN_OUTER_ROUNDS
+#ifdef  AES_COMPACT_IN_OUTER_ROUNDS
+/* AES_COMPACT_IN_OUTER_ROUNDS costs ~30% in performance, while
+ * adding AES_COMPACT_IN_INNER_ROUNDS reduces benchmark *further*
+ * by factor of ~2. */
+# undef  AES_COMPACT_IN_INNER_ROUNDS
+#endif
+
+#if 1
+static void prefetch256(const void *table)
+{
+	volatile unsigned long *t=(void *)table,ret;
+	unsigned long sum;
+	int i;
+
+	/* 32 is common least cache-line size */
+	for (sum=0,i=0;i<256/sizeof(t[0]);i+=32/sizeof(t[0]))	sum ^= t[i];
+
+	ret = sum;
+}
+#else
+# define prefetch256(t)
+#endif
+
+#undef GETU32
+#define GETU32(p) (*((u32*)(p)))
+
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
+typedef unsigned __int64 u64;
+#define U64(C)	C##UI64
+#elif defined(__arch64__)
+typedef unsigned long u64;
+#define U64(C)	C##UL
+#else
+typedef unsigned long long u64;
+#define U64(C)	C##ULL
+#endif
+
+#undef ROTATE
+#if defined(_MSC_VER) || defined(__ICC)
+# define ROTATE(a,n)	_lrotl(a,n)
+#elif defined(__GNUC__) && __GNUC__>=2
+# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+#   define ROTATE(a,n)	({ register unsigned int ret;	\
+				asm (			\
+				"roll %1,%0"		\
+				: "=r"(ret)		\
+				: "I"(n), "0"(a)	\
+				: "cc");		\
+			   ret;				\
+			})
+# endif
+#endif
+/*
+Te [x] = S [x].[02, 01, 01, 03, 02, 01, 01, 03];
+Te0[x] = S [x].[02, 01, 01, 03];
+Te1[x] = S [x].[03, 02, 01, 01];
+Te2[x] = S [x].[01, 03, 02, 01];
+Te3[x] = S [x].[01, 01, 03, 02];
+*/
+#define Te0 (u32)((u64*)((u8*)Te+0))
+#define Te1 (u32)((u64*)((u8*)Te+3))
+#define Te2 (u32)((u64*)((u8*)Te+2))
+#define Te3 (u32)((u64*)((u8*)Te+1))
+/*
+Td [x] = Si[x].[0e, 09, 0d, 0b, 0e, 09, 0d, 0b];
+Td0[x] = Si[x].[0e, 09, 0d, 0b];
+Td1[x] = Si[x].[0b, 0e, 09, 0d];
+Td2[x] = Si[x].[0d, 0b, 0e, 09];
+Td3[x] = Si[x].[09, 0d, 0b, 0e];
+Td4[x] = Si[x].[01];
+*/
+#define Td0 (u32)((u64*)((u8*)Td+0))
+#define Td1 (u32)((u64*)((u8*)Td+3))
+#define Td2 (u32)((u64*)((u8*)Td+2))
+#define Td3 (u32)((u64*)((u8*)Td+1))
+
+static const u64 Te[256] = {
+    U64(0xa56363c6a56363c6), U64(0x847c7cf8847c7cf8),
+    U64(0x997777ee997777ee), U64(0x8d7b7bf68d7b7bf6),
+    U64(0x0df2f2ff0df2f2ff), U64(0xbd6b6bd6bd6b6bd6),
+    U64(0xb16f6fdeb16f6fde), U64(0x54c5c59154c5c591),
+    U64(0x5030306050303060), U64(0x0301010203010102),
+    U64(0xa96767cea96767ce), U64(0x7d2b2b567d2b2b56),
+    U64(0x19fefee719fefee7), U64(0x62d7d7b562d7d7b5),
+    U64(0xe6abab4de6abab4d), U64(0x9a7676ec9a7676ec),
+    U64(0x45caca8f45caca8f), U64(0x9d82821f9d82821f),
+    U64(0x40c9c98940c9c989), U64(0x877d7dfa877d7dfa),
+    U64(0x15fafaef15fafaef), U64(0xeb5959b2eb5959b2),
+    U64(0xc947478ec947478e), U64(0x0bf0f0fb0bf0f0fb),
+    U64(0xecadad41ecadad41), U64(0x67d4d4b367d4d4b3),
+    U64(0xfda2a25ffda2a25f), U64(0xeaafaf45eaafaf45),
+    U64(0xbf9c9c23bf9c9c23), U64(0xf7a4a453f7a4a453),
+    U64(0x967272e4967272e4), U64(0x5bc0c09b5bc0c09b),
+    U64(0xc2b7b775c2b7b775), U64(0x1cfdfde11cfdfde1),
+    U64(0xae93933dae93933d), U64(0x6a26264c6a26264c),
+    U64(0x5a36366c5a36366c), U64(0x413f3f7e413f3f7e),
+    U64(0x02f7f7f502f7f7f5), U64(0x4fcccc834fcccc83),
+    U64(0x5c3434685c343468), U64(0xf4a5a551f4a5a551),
+    U64(0x34e5e5d134e5e5d1), U64(0x08f1f1f908f1f1f9),
+    U64(0x937171e2937171e2), U64(0x73d8d8ab73d8d8ab),
+    U64(0x5331316253313162), U64(0x3f15152a3f15152a),
+    U64(0x0c0404080c040408), U64(0x52c7c79552c7c795),
+    U64(0x6523234665232346), U64(0x5ec3c39d5ec3c39d),
+    U64(0x2818183028181830), U64(0xa1969637a1969637),
+    U64(0x0f05050a0f05050a), U64(0xb59a9a2fb59a9a2f),
+    U64(0x0907070e0907070e), U64(0x3612122436121224),
+    U64(0x9b80801b9b80801b), U64(0x3de2e2df3de2e2df),
+    U64(0x26ebebcd26ebebcd), U64(0x6927274e6927274e),
+    U64(0xcdb2b27fcdb2b27f), U64(0x9f7575ea9f7575ea),
+    U64(0x1b0909121b090912), U64(0x9e83831d9e83831d),
+    U64(0x742c2c58742c2c58), U64(0x2e1a1a342e1a1a34),
+    U64(0x2d1b1b362d1b1b36), U64(0xb26e6edcb26e6edc),
+    U64(0xee5a5ab4ee5a5ab4), U64(0xfba0a05bfba0a05b),
+    U64(0xf65252a4f65252a4), U64(0x4d3b3b764d3b3b76),
+    U64(0x61d6d6b761d6d6b7), U64(0xceb3b37dceb3b37d),
+    U64(0x7b2929527b292952), U64(0x3ee3e3dd3ee3e3dd),
+    U64(0x712f2f5e712f2f5e), U64(0x9784841397848413),
+    U64(0xf55353a6f55353a6), U64(0x68d1d1b968d1d1b9),
+    U64(0x0000000000000000), U64(0x2cededc12cededc1),
+    U64(0x6020204060202040), U64(0x1ffcfce31ffcfce3),
+    U64(0xc8b1b179c8b1b179), U64(0xed5b5bb6ed5b5bb6),
+    U64(0xbe6a6ad4be6a6ad4), U64(0x46cbcb8d46cbcb8d),
+    U64(0xd9bebe67d9bebe67), U64(0x4b3939724b393972),
+    U64(0xde4a4a94de4a4a94), U64(0xd44c4c98d44c4c98),
+    U64(0xe85858b0e85858b0), U64(0x4acfcf854acfcf85),
+    U64(0x6bd0d0bb6bd0d0bb), U64(0x2aefefc52aefefc5),
+    U64(0xe5aaaa4fe5aaaa4f), U64(0x16fbfbed16fbfbed),
+    U64(0xc5434386c5434386), U64(0xd74d4d9ad74d4d9a),
+    U64(0x5533336655333366), U64(0x9485851194858511),
+    U64(0xcf45458acf45458a), U64(0x10f9f9e910f9f9e9),
+    U64(0x0602020406020204), U64(0x817f7ffe817f7ffe),
+    U64(0xf05050a0f05050a0), U64(0x443c3c78443c3c78),
+    U64(0xba9f9f25ba9f9f25), U64(0xe3a8a84be3a8a84b),
+    U64(0xf35151a2f35151a2), U64(0xfea3a35dfea3a35d),
+    U64(0xc0404080c0404080), U64(0x8a8f8f058a8f8f05),
+    U64(0xad92923fad92923f), U64(0xbc9d9d21bc9d9d21),
+    U64(0x4838387048383870), U64(0x04f5f5f104f5f5f1),
+    U64(0xdfbcbc63dfbcbc63), U64(0xc1b6b677c1b6b677),
+    U64(0x75dadaaf75dadaaf), U64(0x6321214263212142),
+    U64(0x3010102030101020), U64(0x1affffe51affffe5),
+    U64(0x0ef3f3fd0ef3f3fd), U64(0x6dd2d2bf6dd2d2bf),
+    U64(0x4ccdcd814ccdcd81), U64(0x140c0c18140c0c18),
+    U64(0x3513132635131326), U64(0x2fececc32fececc3),
+    U64(0xe15f5fbee15f5fbe), U64(0xa2979735a2979735),
+    U64(0xcc444488cc444488), U64(0x3917172e3917172e),
+    U64(0x57c4c49357c4c493), U64(0xf2a7a755f2a7a755),
+    U64(0x827e7efc827e7efc), U64(0x473d3d7a473d3d7a),
+    U64(0xac6464c8ac6464c8), U64(0xe75d5dbae75d5dba),
+    U64(0x2b1919322b191932), U64(0x957373e6957373e6),
+    U64(0xa06060c0a06060c0), U64(0x9881811998818119),
+    U64(0xd14f4f9ed14f4f9e), U64(0x7fdcdca37fdcdca3),
+    U64(0x6622224466222244), U64(0x7e2a2a547e2a2a54),
+    U64(0xab90903bab90903b), U64(0x8388880b8388880b),
+    U64(0xca46468cca46468c), U64(0x29eeeec729eeeec7),
+    U64(0xd3b8b86bd3b8b86b), U64(0x3c1414283c141428),
+    U64(0x79dedea779dedea7), U64(0xe25e5ebce25e5ebc),
+    U64(0x1d0b0b161d0b0b16), U64(0x76dbdbad76dbdbad),
+    U64(0x3be0e0db3be0e0db), U64(0x5632326456323264),
+    U64(0x4e3a3a744e3a3a74), U64(0x1e0a0a141e0a0a14),
+    U64(0xdb494992db494992), U64(0x0a06060c0a06060c),
+    U64(0x6c2424486c242448), U64(0xe45c5cb8e45c5cb8),
+    U64(0x5dc2c29f5dc2c29f), U64(0x6ed3d3bd6ed3d3bd),
+    U64(0xefacac43efacac43), U64(0xa66262c4a66262c4),
+    U64(0xa8919139a8919139), U64(0xa4959531a4959531),
+    U64(0x37e4e4d337e4e4d3), U64(0x8b7979f28b7979f2),
+    U64(0x32e7e7d532e7e7d5), U64(0x43c8c88b43c8c88b),
+    U64(0x5937376e5937376e), U64(0xb76d6ddab76d6dda),
+    U64(0x8c8d8d018c8d8d01), U64(0x64d5d5b164d5d5b1),
+    U64(0xd24e4e9cd24e4e9c), U64(0xe0a9a949e0a9a949),
+    U64(0xb46c6cd8b46c6cd8), U64(0xfa5656acfa5656ac),
+    U64(0x07f4f4f307f4f4f3), U64(0x25eaeacf25eaeacf),
+    U64(0xaf6565caaf6565ca), U64(0x8e7a7af48e7a7af4),
+    U64(0xe9aeae47e9aeae47), U64(0x1808081018080810),
+    U64(0xd5baba6fd5baba6f), U64(0x887878f0887878f0),
+    U64(0x6f25254a6f25254a), U64(0x722e2e5c722e2e5c),
+    U64(0x241c1c38241c1c38), U64(0xf1a6a657f1a6a657),
+    U64(0xc7b4b473c7b4b473), U64(0x51c6c69751c6c697),
+    U64(0x23e8e8cb23e8e8cb), U64(0x7cdddda17cdddda1),
+    U64(0x9c7474e89c7474e8), U64(0x211f1f3e211f1f3e),
+    U64(0xdd4b4b96dd4b4b96), U64(0xdcbdbd61dcbdbd61),
+    U64(0x868b8b0d868b8b0d), U64(0x858a8a0f858a8a0f),
+    U64(0x907070e0907070e0), U64(0x423e3e7c423e3e7c),
+    U64(0xc4b5b571c4b5b571), U64(0xaa6666ccaa6666cc),
+    U64(0xd8484890d8484890), U64(0x0503030605030306),
+    U64(0x01f6f6f701f6f6f7), U64(0x120e0e1c120e0e1c),
+    U64(0xa36161c2a36161c2), U64(0x5f35356a5f35356a),
+    U64(0xf95757aef95757ae), U64(0xd0b9b969d0b9b969),
+    U64(0x9186861791868617), U64(0x58c1c19958c1c199),
+    U64(0x271d1d3a271d1d3a), U64(0xb99e9e27b99e9e27),
+    U64(0x38e1e1d938e1e1d9), U64(0x13f8f8eb13f8f8eb),
+    U64(0xb398982bb398982b), U64(0x3311112233111122),
+    U64(0xbb6969d2bb6969d2), U64(0x70d9d9a970d9d9a9),
+    U64(0x898e8e07898e8e07), U64(0xa7949433a7949433),
+    U64(0xb69b9b2db69b9b2d), U64(0x221e1e3c221e1e3c),
+    U64(0x9287871592878715), U64(0x20e9e9c920e9e9c9),
+    U64(0x49cece8749cece87), U64(0xff5555aaff5555aa),
+    U64(0x7828285078282850), U64(0x7adfdfa57adfdfa5),
+    U64(0x8f8c8c038f8c8c03), U64(0xf8a1a159f8a1a159),
+    U64(0x8089890980898909), U64(0x170d0d1a170d0d1a),
+    U64(0xdabfbf65dabfbf65), U64(0x31e6e6d731e6e6d7),
+    U64(0xc6424284c6424284), U64(0xb86868d0b86868d0),
+    U64(0xc3414182c3414182), U64(0xb0999929b0999929),
+    U64(0x772d2d5a772d2d5a), U64(0x110f0f1e110f0f1e),
+    U64(0xcbb0b07bcbb0b07b), U64(0xfc5454a8fc5454a8),
+    U64(0xd6bbbb6dd6bbbb6d), U64(0x3a16162c3a16162c)
+};
+
+static const u8 Te4[256] = {
+    0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U,
+    0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U,
+    0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U,
+    0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U,
+    0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU,
+    0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U,
+    0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU,
+    0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U,
+    0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U,
+    0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U,
+    0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU,
+    0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU,
+    0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U,
+    0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U,
+    0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U,
+    0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U,
+    0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U,
+    0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U,
+    0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U,
+    0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU,
+    0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU,
+    0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U,
+    0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U,
+    0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U,
+    0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U,
+    0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU,
+    0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU,
+    0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU,
+    0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U,
+    0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU,
+    0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U,
+    0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
+};
+
+static const u64 Td[256] = {
+    U64(0x50a7f45150a7f451), U64(0x5365417e5365417e),
+    U64(0xc3a4171ac3a4171a), U64(0x965e273a965e273a),
+    U64(0xcb6bab3bcb6bab3b), U64(0xf1459d1ff1459d1f),
+    U64(0xab58faacab58faac), U64(0x9303e34b9303e34b),
+    U64(0x55fa302055fa3020), U64(0xf66d76adf66d76ad),
+    U64(0x9176cc889176cc88), U64(0x254c02f5254c02f5),
+    U64(0xfcd7e54ffcd7e54f), U64(0xd7cb2ac5d7cb2ac5),
+    U64(0x8044352680443526), U64(0x8fa362b58fa362b5),
+    U64(0x495ab1de495ab1de), U64(0x671bba25671bba25),
+    U64(0x980eea45980eea45), U64(0xe1c0fe5de1c0fe5d),
+    U64(0x02752fc302752fc3), U64(0x12f04c8112f04c81),
+    U64(0xa397468da397468d), U64(0xc6f9d36bc6f9d36b),
+    U64(0xe75f8f03e75f8f03), U64(0x959c9215959c9215),
+    U64(0xeb7a6dbfeb7a6dbf), U64(0xda595295da595295),
+    U64(0x2d83bed42d83bed4), U64(0xd3217458d3217458),
+    U64(0x2969e0492969e049), U64(0x44c8c98e44c8c98e),
+    U64(0x6a89c2756a89c275), U64(0x78798ef478798ef4),
+    U64(0x6b3e58996b3e5899), U64(0xdd71b927dd71b927),
+    U64(0xb64fe1beb64fe1be), U64(0x17ad88f017ad88f0),
+    U64(0x66ac20c966ac20c9), U64(0xb43ace7db43ace7d),
+    U64(0x184adf63184adf63), U64(0x82311ae582311ae5),
+    U64(0x6033519760335197), U64(0x457f5362457f5362),
+    U64(0xe07764b1e07764b1), U64(0x84ae6bbb84ae6bbb),
+    U64(0x1ca081fe1ca081fe), U64(0x942b08f9942b08f9),
+    U64(0x5868487058684870), U64(0x19fd458f19fd458f),
+    U64(0x876cde94876cde94), U64(0xb7f87b52b7f87b52),
+    U64(0x23d373ab23d373ab), U64(0xe2024b72e2024b72),
+    U64(0x578f1fe3578f1fe3), U64(0x2aab55662aab5566),
+    U64(0x0728ebb20728ebb2), U64(0x03c2b52f03c2b52f),
+    U64(0x9a7bc5869a7bc586), U64(0xa50837d3a50837d3),
+    U64(0xf2872830f2872830), U64(0xb2a5bf23b2a5bf23),
+    U64(0xba6a0302ba6a0302), U64(0x5c8216ed5c8216ed),
+    U64(0x2b1ccf8a2b1ccf8a), U64(0x92b479a792b479a7),
+    U64(0xf0f207f3f0f207f3), U64(0xa1e2694ea1e2694e),
+    U64(0xcdf4da65cdf4da65), U64(0xd5be0506d5be0506),
+    U64(0x1f6234d11f6234d1), U64(0x8afea6c48afea6c4),
+    U64(0x9d532e349d532e34), U64(0xa055f3a2a055f3a2),
+    U64(0x32e18a0532e18a05), U64(0x75ebf6a475ebf6a4),
+    U64(0x39ec830b39ec830b), U64(0xaaef6040aaef6040),
+    U64(0x069f715e069f715e), U64(0x51106ebd51106ebd),
+    U64(0xf98a213ef98a213e), U64(0x3d06dd963d06dd96),
+    U64(0xae053eddae053edd), U64(0x46bde64d46bde64d),
+    U64(0xb58d5491b58d5491), U64(0x055dc471055dc471),
+    U64(0x6fd406046fd40604), U64(0xff155060ff155060),
+    U64(0x24fb981924fb9819), U64(0x97e9bdd697e9bdd6),
+    U64(0xcc434089cc434089), U64(0x779ed967779ed967),
+    U64(0xbd42e8b0bd42e8b0), U64(0x888b8907888b8907),
+    U64(0x385b19e7385b19e7), U64(0xdbeec879dbeec879),
+    U64(0x470a7ca1470a7ca1), U64(0xe90f427ce90f427c),
+    U64(0xc91e84f8c91e84f8), U64(0x0000000000000000),
+    U64(0x8386800983868009), U64(0x48ed2b3248ed2b32),
+    U64(0xac70111eac70111e), U64(0x4e725a6c4e725a6c),
+    U64(0xfbff0efdfbff0efd), U64(0x5638850f5638850f),
+    U64(0x1ed5ae3d1ed5ae3d), U64(0x27392d3627392d36),
+    U64(0x64d90f0a64d90f0a), U64(0x21a65c6821a65c68),
+    U64(0xd1545b9bd1545b9b), U64(0x3a2e36243a2e3624),
+    U64(0xb1670a0cb1670a0c), U64(0x0fe757930fe75793),
+    U64(0xd296eeb4d296eeb4), U64(0x9e919b1b9e919b1b),
+    U64(0x4fc5c0804fc5c080), U64(0xa220dc61a220dc61),
+    U64(0x694b775a694b775a), U64(0x161a121c161a121c),
+    U64(0x0aba93e20aba93e2), U64(0xe52aa0c0e52aa0c0),
+    U64(0x43e0223c43e0223c), U64(0x1d171b121d171b12),
+    U64(0x0b0d090e0b0d090e), U64(0xadc78bf2adc78bf2),
+    U64(0xb9a8b62db9a8b62d), U64(0xc8a91e14c8a91e14),
+    U64(0x8519f1578519f157), U64(0x4c0775af4c0775af),
+    U64(0xbbdd99eebbdd99ee), U64(0xfd607fa3fd607fa3),
+    U64(0x9f2601f79f2601f7), U64(0xbcf5725cbcf5725c),
+    U64(0xc53b6644c53b6644), U64(0x347efb5b347efb5b),
+    U64(0x7629438b7629438b), U64(0xdcc623cbdcc623cb),
+    U64(0x68fcedb668fcedb6), U64(0x63f1e4b863f1e4b8),
+    U64(0xcadc31d7cadc31d7), U64(0x1085634210856342),
+    U64(0x4022971340229713), U64(0x2011c6842011c684),
+    U64(0x7d244a857d244a85), U64(0xf83dbbd2f83dbbd2),
+    U64(0x1132f9ae1132f9ae), U64(0x6da129c76da129c7),
+    U64(0x4b2f9e1d4b2f9e1d), U64(0xf330b2dcf330b2dc),
+    U64(0xec52860dec52860d), U64(0xd0e3c177d0e3c177),
+    U64(0x6c16b32b6c16b32b), U64(0x99b970a999b970a9),
+    U64(0xfa489411fa489411), U64(0x2264e9472264e947),
+    U64(0xc48cfca8c48cfca8), U64(0x1a3ff0a01a3ff0a0),
+    U64(0xd82c7d56d82c7d56), U64(0xef903322ef903322),
+    U64(0xc74e4987c74e4987), U64(0xc1d138d9c1d138d9),
+    U64(0xfea2ca8cfea2ca8c), U64(0x360bd498360bd498),
+    U64(0xcf81f5a6cf81f5a6), U64(0x28de7aa528de7aa5),
+    U64(0x268eb7da268eb7da), U64(0xa4bfad3fa4bfad3f),
+    U64(0xe49d3a2ce49d3a2c), U64(0x0d9278500d927850),
+    U64(0x9bcc5f6a9bcc5f6a), U64(0x62467e5462467e54),
+    U64(0xc2138df6c2138df6), U64(0xe8b8d890e8b8d890),
+    U64(0x5ef7392e5ef7392e), U64(0xf5afc382f5afc382),
+    U64(0xbe805d9fbe805d9f), U64(0x7c93d0697c93d069),
+    U64(0xa92dd56fa92dd56f), U64(0xb31225cfb31225cf),
+    U64(0x3b99acc83b99acc8), U64(0xa77d1810a77d1810),
+    U64(0x6e639ce86e639ce8), U64(0x7bbb3bdb7bbb3bdb),
+    U64(0x097826cd097826cd), U64(0xf418596ef418596e),
+    U64(0x01b79aec01b79aec), U64(0xa89a4f83a89a4f83),
+    U64(0x656e95e6656e95e6), U64(0x7ee6ffaa7ee6ffaa),
+    U64(0x08cfbc2108cfbc21), U64(0xe6e815efe6e815ef),
+    U64(0xd99be7bad99be7ba), U64(0xce366f4ace366f4a),
+    U64(0xd4099fead4099fea), U64(0xd67cb029d67cb029),
+    U64(0xafb2a431afb2a431), U64(0x31233f2a31233f2a),
+    U64(0x3094a5c63094a5c6), U64(0xc066a235c066a235),
+    U64(0x37bc4e7437bc4e74), U64(0xa6ca82fca6ca82fc),
+    U64(0xb0d090e0b0d090e0), U64(0x15d8a73315d8a733),
+    U64(0x4a9804f14a9804f1), U64(0xf7daec41f7daec41),
+    U64(0x0e50cd7f0e50cd7f), U64(0x2ff691172ff69117),
+    U64(0x8dd64d768dd64d76), U64(0x4db0ef434db0ef43),
+    U64(0x544daacc544daacc), U64(0xdf0496e4df0496e4),
+    U64(0xe3b5d19ee3b5d19e), U64(0x1b886a4c1b886a4c),
+    U64(0xb81f2cc1b81f2cc1), U64(0x7f5165467f516546),
+    U64(0x04ea5e9d04ea5e9d), U64(0x5d358c015d358c01),
+    U64(0x737487fa737487fa), U64(0x2e410bfb2e410bfb),
+    U64(0x5a1d67b35a1d67b3), U64(0x52d2db9252d2db92),
+    U64(0x335610e9335610e9), U64(0x1347d66d1347d66d),
+    U64(0x8c61d79a8c61d79a), U64(0x7a0ca1377a0ca137),
+    U64(0x8e14f8598e14f859), U64(0x893c13eb893c13eb),
+    U64(0xee27a9ceee27a9ce), U64(0x35c961b735c961b7),
+    U64(0xede51ce1ede51ce1), U64(0x3cb1477a3cb1477a),
+    U64(0x59dfd29c59dfd29c), U64(0x3f73f2553f73f255),
+    U64(0x79ce141879ce1418), U64(0xbf37c773bf37c773),
+    U64(0xeacdf753eacdf753), U64(0x5baafd5f5baafd5f),
+    U64(0x146f3ddf146f3ddf), U64(0x86db447886db4478),
+    U64(0x81f3afca81f3afca), U64(0x3ec468b93ec468b9),
+    U64(0x2c3424382c342438), U64(0x5f40a3c25f40a3c2),
+    U64(0x72c31d1672c31d16), U64(0x0c25e2bc0c25e2bc),
+    U64(0x8b493c288b493c28), U64(0x41950dff41950dff),
+    U64(0x7101a8397101a839), U64(0xdeb30c08deb30c08),
+    U64(0x9ce4b4d89ce4b4d8), U64(0x90c1566490c15664),
+    U64(0x6184cb7b6184cb7b), U64(0x70b632d570b632d5),
+    U64(0x745c6c48745c6c48), U64(0x4257b8d04257b8d0)
+};
+static const u8 Td4[256] = {
+    0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
+    0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
+    0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
+    0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
+    0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
+    0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
+    0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
+    0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
+    0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
+    0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
+    0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
+    0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
+    0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
+    0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
+    0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
+    0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
+    0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
+    0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
+    0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
+    0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
+    0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
+    0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
+    0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
+    0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
+    0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
+    0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
+    0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
+    0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
+    0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
+    0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
+    0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
+    0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU
+};
+
+static const u32 rcon[] = {
+    0x00000001U, 0x00000002U, 0x00000004U, 0x00000008U,
+    0x00000010U, 0x00000020U, 0x00000040U, 0x00000080U,
+    0x0000001bU, 0x00000036U, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+
+/**
+ * Expand the cipher key into the encryption key schedule.
+ */
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+			AES_KEY *key) {
+
+	u32 *rk;
+   	int i = 0;
+	u32 temp;
+
+	if (!userKey || !key)
+		return -1;
+	if (bits != 128 && bits != 192 && bits != 256)
+		return -2;
+
+	rk = key->rd_key;
+
+	if (bits==128)
+		key->rounds = 10;
+	else if (bits==192)
+		key->rounds = 12;
+	else
+		key->rounds = 14;
+
+	rk[0] = GETU32(userKey     );
+	rk[1] = GETU32(userKey +  4);
+	rk[2] = GETU32(userKey +  8);
+	rk[3] = GETU32(userKey + 12);
+	if (bits == 128) {
+		while (1) {
+			temp  = rk[3];
+			rk[4] = rk[0] ^
+				(Te4[(temp >>  8) & 0xff]      ) ^
+				(Te4[(temp >> 16) & 0xff] <<  8) ^
+				(Te4[(temp >> 24)       ] << 16) ^
+				(Te4[(temp      ) & 0xff] << 24) ^
+				rcon[i];
+			rk[5] = rk[1] ^ rk[4];
+			rk[6] = rk[2] ^ rk[5];
+			rk[7] = rk[3] ^ rk[6];
+			if (++i == 10) {
+				return 0;
+			}
+			rk += 4;
+		}
+	}
+	rk[4] = GETU32(userKey + 16);
+	rk[5] = GETU32(userKey + 20);
+	if (bits == 192) {
+		while (1) {
+			temp = rk[ 5];
+			rk[ 6] = rk[ 0] ^
+				(Te4[(temp >>  8) & 0xff]      ) ^
+				(Te4[(temp >> 16) & 0xff] <<  8) ^
+				(Te4[(temp >> 24)       ] << 16) ^
+				(Te4[(temp      ) & 0xff] << 24) ^
+				rcon[i];
+			rk[ 7] = rk[ 1] ^ rk[ 6];
+			rk[ 8] = rk[ 2] ^ rk[ 7];
+			rk[ 9] = rk[ 3] ^ rk[ 8];
+			if (++i == 8) {
+				return 0;
+			}
+			rk[10] = rk[ 4] ^ rk[ 9];
+			rk[11] = rk[ 5] ^ rk[10];
+			rk += 6;
+		}
+	}
+	rk[6] = GETU32(userKey + 24);
+	rk[7] = GETU32(userKey + 28);
+	if (bits == 256) {
+		while (1) {
+			temp = rk[ 7];
+			rk[ 8] = rk[ 0] ^
+				(Te4[(temp >>  8) & 0xff]      ) ^
+				(Te4[(temp >> 16) & 0xff] <<  8) ^
+				(Te4[(temp >> 24)       ] << 16) ^
+				(Te4[(temp      ) & 0xff] << 24) ^
+				rcon[i];
+			rk[ 9] = rk[ 1] ^ rk[ 8];
+			rk[10] = rk[ 2] ^ rk[ 9];
+			rk[11] = rk[ 3] ^ rk[10];
+			if (++i == 7) {
+				return 0;
+			}
+			temp = rk[11];
+			rk[12] = rk[ 4] ^
+				(Te4[(temp      ) & 0xff]      ) ^
+				(Te4[(temp >>  8) & 0xff] <<  8) ^
+				(Te4[(temp >> 16) & 0xff] << 16) ^
+				(Te4[(temp >> 24)       ] << 24);
+			rk[13] = rk[ 5] ^ rk[12];
+			rk[14] = rk[ 6] ^ rk[13];
+			rk[15] = rk[ 7] ^ rk[14];
+
+			rk += 8;
+        	}
+	}
+	return 0;
+}
+
+/**
+ * Expand the cipher key into the decryption key schedule.
+ */
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+			 AES_KEY *key) {
+
+        u32 *rk;
+	int i, j, status;
+	u32 temp;
+
+	/* first, start with an encryption schedule */
+	status = AES_set_encrypt_key(userKey, bits, key);
+	if (status < 0)
+		return status;
+
+	rk = key->rd_key;
+
+	/* invert the order of the round keys: */
+	for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
+		temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
+		temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
+		temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
+		temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
+	}
+	/* apply the inverse MixColumn transform to all round keys but the first and the last: */
+	for (i = 1; i < (key->rounds); i++) {
+		rk += 4;
+#if 1
+		for (j = 0; j < 4; j++) {
+			u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
+
+			tp1 = rk[j];
+			m = tp1 & 0x80808080;
+			tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp2 & 0x80808080;
+			tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp4 & 0x80808080;
+			tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			tp9 = tp8 ^ tp1;
+			tpb = tp9 ^ tp2;
+			tpd = tp9 ^ tp4;
+			tpe = tp8 ^ tp4 ^ tp2;
+#if defined(ROTATE)
+			rk[j] = tpe ^ ROTATE(tpd,16) ^
+				ROTATE(tp9,8) ^ ROTATE(tpb,24);
+#else
+			rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ 
+				(tp9 >> 24) ^ (tp9 << 8) ^
+				(tpb >> 8) ^ (tpb << 24);
+#endif
+		}
+#else
+		rk[0] =
+			Td0[Te2[(rk[0]      ) & 0xff] & 0xff] ^
+			Td1[Te2[(rk[0] >>  8) & 0xff] & 0xff] ^
+			Td2[Te2[(rk[0] >> 16) & 0xff] & 0xff] ^
+			Td3[Te2[(rk[0] >> 24)       ] & 0xff];
+		rk[1] =
+			Td0[Te2[(rk[1]      ) & 0xff] & 0xff] ^
+			Td1[Te2[(rk[1] >>  8) & 0xff] & 0xff] ^
+			Td2[Te2[(rk[1] >> 16) & 0xff] & 0xff] ^
+			Td3[Te2[(rk[1] >> 24)       ] & 0xff];
+		rk[2] =
+			Td0[Te2[(rk[2]      ) & 0xff] & 0xff] ^
+			Td1[Te2[(rk[2] >>  8) & 0xff] & 0xff] ^
+			Td2[Te2[(rk[2] >> 16) & 0xff] & 0xff] ^
+			Td3[Te2[(rk[2] >> 24)       ] & 0xff];
+		rk[3] =
+			Td0[Te2[(rk[3]      ) & 0xff] & 0xff] ^
+			Td1[Te2[(rk[3] >>  8) & 0xff] & 0xff] ^
+			Td2[Te2[(rk[3] >> 16) & 0xff] & 0xff] ^
+			Td3[Te2[(rk[3] >> 24)       ] & 0xff];
+#endif
+	}
+	return 0;
+}
+
+/*
+ * Encrypt a single block
+ * in and out can overlap
+ */
+void AES_encrypt(const unsigned char *in, unsigned char *out,
+		 const AES_KEY *key) {
+
+	const u32 *rk;
+	u32 s0, s1, s2, s3, t[4];
+	int r;
+
+	assert(in && out && key);
+	rk = key->rd_key;
+
+	/*
+	 * map byte array block to cipher state
+	 * and add initial round key:
+	 */
+	s0 = GETU32(in     ) ^ rk[0];
+	s1 = GETU32(in +  4) ^ rk[1];
+	s2 = GETU32(in +  8) ^ rk[2];
+	s3 = GETU32(in + 12) ^ rk[3];
+
+#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
+	prefetch256(Te4);
+
+	t[0] =	Te4[(s0      ) & 0xff]       ^
+		Te4[(s1 >>  8) & 0xff] <<  8 ^
+		Te4[(s2 >> 16) & 0xff] << 16 ^
+		Te4[(s3 >> 24)       ] << 24;
+	t[1] =	Te4[(s1      ) & 0xff]       ^
+		Te4[(s2 >>  8) & 0xff] <<  8 ^
+		Te4[(s3 >> 16) & 0xff] << 16 ^
+		Te4[(s0 >> 24)       ] << 24;
+	t[2] =	Te4[(s2      ) & 0xff]       ^
+		Te4[(s3 >>  8) & 0xff] <<  8 ^
+		Te4[(s0 >> 16) & 0xff] << 16 ^
+		Te4[(s1 >> 24)       ] << 24;
+	t[3] =	Te4[(s3      ) & 0xff]       ^
+		Te4[(s0 >>  8) & 0xff] <<  8 ^
+		Te4[(s1 >> 16) & 0xff] << 16 ^
+		Te4[(s2 >> 24)       ] << 24;
+
+	/* now do the linear transform using words */
+	{	int i;
+		u32 r0, r1, r2;
+
+		for (i = 0; i < 4; i++) {
+			r0 = t[i];
+			r1 = r0 & 0x80808080;
+			r2 = ((r0 & 0x7f7f7f7f) << 1) ^
+				((r1 - (r1 >> 7)) & 0x1b1b1b1b);
+#if defined(ROTATE)
+			t[i] = r2 ^ ROTATE(r2,24) ^ ROTATE(r0,24) ^
+				ROTATE(r0,16) ^ ROTATE(r0,8);
+#else
+			t[i] = r2 ^ ((r2 ^ r0) << 24) ^ ((r2 ^ r0) >> 8) ^
+				(r0 << 16) ^ (r0 >> 16) ^
+				(r0 << 8) ^ (r0 >> 24);
+#endif
+			t[i] ^= rk[4+i];
+		}
+	}
+#else
+	t[0] =	Te0[(s0      ) & 0xff] ^
+		Te1[(s1 >>  8) & 0xff] ^
+		Te2[(s2 >> 16) & 0xff] ^
+		Te3[(s3 >> 24)       ] ^
+		rk[4];
+	t[1] =	Te0[(s1      ) & 0xff] ^
+		Te1[(s2 >>  8) & 0xff] ^
+		Te2[(s3 >> 16) & 0xff] ^
+		Te3[(s0 >> 24)       ] ^
+		rk[5];
+	t[2] =	Te0[(s2      ) & 0xff] ^
+		Te1[(s3 >>  8) & 0xff] ^
+		Te2[(s0 >> 16) & 0xff] ^
+		Te3[(s1 >> 24)       ] ^
+		rk[6];
+	t[3] =	Te0[(s3      ) & 0xff] ^
+		Te1[(s0 >>  8) & 0xff] ^
+		Te2[(s1 >> 16) & 0xff] ^
+		Te3[(s2 >> 24)       ] ^
+		rk[7];
+#endif
+	s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
+
+    /*
+     * Nr - 2 full rounds:
+     */
+    for (rk+=8,r=key->rounds-2; r>0; rk+=4,r--) {
+#if defined(AES_COMPACT_IN_INNER_ROUNDS)
+	t[0] =	Te4[(s0      ) & 0xff]       ^
+		Te4[(s1 >>  8) & 0xff] <<  8 ^
+		Te4[(s2 >> 16) & 0xff] << 16 ^
+		Te4[(s3 >> 24)       ] << 24;
+	t[1] =	Te4[(s1      ) & 0xff]       ^
+		Te4[(s2 >>  8) & 0xff] <<  8 ^
+		Te4[(s3 >> 16) & 0xff] << 16 ^
+		Te4[(s0 >> 24)       ] << 24;
+	t[2] =	Te4[(s2      ) & 0xff]       ^
+		Te4[(s3 >>  8) & 0xff] <<  8 ^
+		Te4[(s0 >> 16) & 0xff] << 16 ^
+		Te4[(s1 >> 24)       ] << 24;
+	t[3] =	Te4[(s3      ) & 0xff]       ^
+		Te4[(s0 >>  8) & 0xff] <<  8 ^
+		Te4[(s1 >> 16) & 0xff] << 16 ^
+		Te4[(s2 >> 24)       ] << 24;
+
+	/* now do the linear transform using words */
+	{	int i;
+		u32 r0, r1, r2;
+
+		for (i = 0; i < 4; i++) {
+			r0 = t[i];
+			r1 = r0 & 0x80808080;
+			r2 = ((r0 & 0x7f7f7f7f) << 1) ^
+				((r1 - (r1 >> 7)) & 0x1b1b1b1b);
+#if defined(ROTATE)
+			t[i] = r2 ^ ROTATE(r2,24) ^ ROTATE(r0,24) ^
+				ROTATE(r0,16) ^ ROTATE(r0,8);
+#else
+			t[i] = r2 ^ ((r2 ^ r0) << 24) ^ ((r2 ^ r0) >> 8) ^
+				(r0 << 16) ^ (r0 >> 16) ^
+				(r0 << 8) ^ (r0 >> 24);
+#endif
+			t[i] ^= rk[i];
+		}
+	}
+#else
+	t[0] =	Te0[(s0      ) & 0xff] ^
+		Te1[(s1 >>  8) & 0xff] ^
+		Te2[(s2 >> 16) & 0xff] ^
+		Te3[(s3 >> 24)       ] ^
+		rk[0];
+	t[1] =	Te0[(s1      ) & 0xff] ^
+		Te1[(s2 >>  8) & 0xff] ^
+		Te2[(s3 >> 16) & 0xff] ^
+		Te3[(s0 >> 24)       ] ^
+		rk[1];
+	t[2] =	Te0[(s2      ) & 0xff] ^
+		Te1[(s3 >>  8) & 0xff] ^
+		Te2[(s0 >> 16) & 0xff] ^
+		Te3[(s1 >> 24)       ] ^
+		rk[2];
+	t[3] =	Te0[(s3      ) & 0xff] ^
+		Te1[(s0 >>  8) & 0xff] ^
+		Te2[(s1 >> 16) & 0xff] ^
+		Te3[(s2 >> 24)       ] ^
+		rk[3];
+#endif
+	s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
+    }
+    /*
+	 * apply last round and
+	 * map cipher state to byte array block:
+	 */
+#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
+	prefetch256(Te4);
+
+	*(u32*)(out+0) =
+		Te4[(s0      ) & 0xff]       ^
+		Te4[(s1 >>  8) & 0xff] <<  8 ^
+		Te4[(s2 >> 16) & 0xff] << 16 ^
+		Te4[(s3 >> 24)       ] << 24 ^
+		rk[0];
+	*(u32*)(out+4) =
+		Te4[(s1      ) & 0xff]       ^
+		Te4[(s2 >>  8) & 0xff] <<  8 ^
+		Te4[(s3 >> 16) & 0xff] << 16 ^
+		Te4[(s0 >> 24)       ] << 24 ^
+		rk[1];
+	*(u32*)(out+8) =
+		Te4[(s2      ) & 0xff]       ^
+		Te4[(s3 >>  8) & 0xff] <<  8 ^
+		Te4[(s0 >> 16) & 0xff] << 16 ^
+		Te4[(s1 >> 24)       ] << 24 ^
+		rk[2];
+	*(u32*)(out+12) =
+		Te4[(s3      ) & 0xff]       ^
+		Te4[(s0 >>  8) & 0xff] <<  8 ^
+		Te4[(s1 >> 16) & 0xff] << 16 ^
+		Te4[(s2 >> 24)       ] << 24 ^
+		rk[3];
+#else
+	*(u32*)(out+0) =
+		(Te2[(s0      ) & 0xff] & 0x000000ffU) ^
+		(Te3[(s1 >>  8) & 0xff] & 0x0000ff00U) ^
+		(Te0[(s2 >> 16) & 0xff] & 0x00ff0000U) ^
+		(Te1[(s3 >> 24)       ] & 0xff000000U) ^
+		rk[0];
+	*(u32*)(out+4) =
+		(Te2[(s1      ) & 0xff] & 0x000000ffU) ^
+		(Te3[(s2 >>  8) & 0xff] & 0x0000ff00U) ^
+		(Te0[(s3 >> 16) & 0xff] & 0x00ff0000U) ^
+		(Te1[(s0 >> 24)       ] & 0xff000000U) ^
+		rk[1];
+	*(u32*)(out+8) =
+		(Te2[(s2      ) & 0xff] & 0x000000ffU) ^
+		(Te3[(s3 >>  8) & 0xff] & 0x0000ff00U) ^
+		(Te0[(s0 >> 16) & 0xff] & 0x00ff0000U) ^
+		(Te1[(s1 >> 24)       ] & 0xff000000U) ^
+		rk[2];
+	*(u32*)(out+12) =
+		(Te2[(s3      ) & 0xff] & 0x000000ffU) ^
+		(Te3[(s0 >>  8) & 0xff] & 0x0000ff00U) ^
+		(Te0[(s1 >> 16) & 0xff] & 0x00ff0000U) ^
+		(Te1[(s2 >> 24)       ] & 0xff000000U) ^
+		rk[3];
+#endif
+}
+
+/*
+ * Decrypt a single block
+ * in and out can overlap
+ */
+void AES_decrypt(const unsigned char *in, unsigned char *out,
+		 const AES_KEY *key) {
+
+	const u32 *rk;
+	u32 s0, s1, s2, s3, t[4];
+	int r;
+
+	assert(in && out && key);
+	rk = key->rd_key;
+
+	/*
+	 * map byte array block to cipher state
+	 * and add initial round key:
+	 */
+	s0 = GETU32(in     ) ^ rk[0];
+	s1 = GETU32(in +  4) ^ rk[1];
+	s2 = GETU32(in +  8) ^ rk[2];
+	s3 = GETU32(in + 12) ^ rk[3];
+
+#if defined(AES_COMPACT_IN_OUTER_ROUNDS)
+	prefetch256(Td4);
+
+        t[0] =	Td4[(s0      ) & 0xff]       ^
+		Td4[(s3 >>  8) & 0xff] <<  8 ^
+		Td4[(s2 >> 16) & 0xff] << 16 ^
+		Td4[(s1 >> 24)       ] << 24;
+        t[1] =	Td4[(s1      ) & 0xff]       ^
+		Td4[(s0 >>  8) & 0xff] <<  8 ^
+		Td4[(s3 >> 16) & 0xff] << 16 ^
+		Td4[(s2 >> 24)       ] << 24;
+        t[2] =	Td4[(s2      ) & 0xff]       ^
+		Td4[(s1 >>  8) & 0xff] <<  8 ^
+		Td4[(s0 >> 16) & 0xff] << 16 ^
+		Td4[(s3 >> 24)       ] << 24;
+        t[3] =	Td4[(s3      ) & 0xff]       ^
+		Td4[(s2 >>  8) & 0xff] <<  8 ^
+		Td4[(s1 >> 16) & 0xff] << 16 ^
+		Td4[(s0 >> 24)       ] << 24;
+
+	/* now do the linear transform using words */ 
+	{	int i;
+		u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
+
+		for (i = 0; i < 4; i++) {
+			tp1 = t[i];
+			m = tp1 & 0x80808080;
+			tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp2 & 0x80808080;
+			tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp4 & 0x80808080;
+			tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			tp9 = tp8 ^ tp1;
+			tpb = tp9 ^ tp2;
+			tpd = tp9 ^ tp4;
+			tpe = tp8 ^ tp4 ^ tp2;
+#if defined(ROTATE)
+			t[i] = tpe ^ ROTATE(tpd,16) ^
+				ROTATE(tp9,8) ^ ROTATE(tpb,24);
+#else
+			t[i] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ 
+				(tp9 >> 24) ^ (tp9 << 8) ^
+				(tpb >> 8) ^ (tpb << 24);
+#endif
+			t[i] ^= rk[4+i];
+		}
+	}
+#else
+	t[0] =	Td0[(s0      ) & 0xff] ^
+		Td1[(s3 >>  8) & 0xff] ^
+		Td2[(s2 >> 16) & 0xff] ^
+		Td3[(s1 >> 24)       ] ^
+		rk[4];
+	t[1] =	Td0[(s1      ) & 0xff] ^
+		Td1[(s0 >>  8) & 0xff] ^
+		Td2[(s3 >> 16) & 0xff] ^
+		Td3[(s2 >> 24)       ] ^
+		rk[5];
+	t[2] =	Td0[(s2      ) & 0xff] ^
+		Td1[(s1 >>  8) & 0xff] ^
+		Td2[(s0 >> 16) & 0xff] ^
+		Td3[(s3 >> 24)       ] ^
+		rk[6];
+	t[3] =	Td0[(s3      ) & 0xff] ^
+		Td1[(s2 >>  8) & 0xff] ^
+		Td2[(s1 >> 16) & 0xff] ^
+		Td3[(s0 >> 24)       ] ^
+		rk[7];
+#endif
+	s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
+
+    /*
+     * Nr - 2 full rounds:
+     */
+    for (rk+=8,r=key->rounds-2; r>0; rk+=4,r--) {
+#if defined(AES_COMPACT_IN_INNER_ROUNDS)
+        t[0] =	Td4[(s0      ) & 0xff]       ^
+		Td4[(s3 >>  8) & 0xff] <<  8 ^
+		Td4[(s2 >> 16) & 0xff] << 16 ^
+		Td4[(s1 >> 24)       ] << 24;
+        t[1] =	Td4[(s1      ) & 0xff]       ^
+		Td4[(s0 >>  8) & 0xff] <<  8 ^
+		Td4[(s3 >> 16) & 0xff] << 16 ^
+		Td4[(s2 >> 24)       ] << 24;
+        t[2] =	Td4[(s2      ) & 0xff]       ^
+		Td4[(s1 >>  8) & 0xff] <<  8 ^
+		Td4[(s0 >> 16) & 0xff] << 16 ^
+		Td4[(s3 >> 24)       ] << 24;
+        t[3] =	Td4[(s3      ) & 0xff]       ^
+		Td4[(s2 >>  8) & 0xff] <<  8 ^
+		Td4[(s1 >> 16) & 0xff] << 16 ^
+		Td4[(s0 >> 24)       ] << 24;
+
+	/* now do the linear transform using words */ 
+	{	int i;
+		u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
+
+		for (i = 0; i < 4; i++) {
+			tp1 = t[i];
+			m = tp1 & 0x80808080;
+			tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp2 & 0x80808080;
+			tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			m = tp4 & 0x80808080;
+			tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
+				((m - (m >> 7)) & 0x1b1b1b1b);
+			tp9 = tp8 ^ tp1;
+			tpb = tp9 ^ tp2;
+			tpd = tp9 ^ tp4;
+			tpe = tp8 ^ tp4 ^ tp2;
+#if defined(ROTATE)
+			t[i] = tpe ^ ROTATE(tpd,16) ^
+				ROTATE(tp9,8) ^ ROTATE(tpb,24);
+#else
+			t[i] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ 
+				(tp9 >> 24) ^ (tp9 << 8) ^
+				(tpb >> 8) ^ (tpb << 24);
+#endif
+			t[i] ^= rk[i];
+		}
+	}
+#else
+	t[0] =	Td0[(s0      ) & 0xff] ^
+		Td1[(s3 >>  8) & 0xff] ^
+		Td2[(s2 >> 16) & 0xff] ^
+		Td3[(s1 >> 24)       ] ^
+		rk[0];
+	t[1] =	Td0[(s1      ) & 0xff] ^
+		Td1[(s0 >>  8) & 0xff] ^
+		Td2[(s3 >> 16) & 0xff] ^
+		Td3[(s2 >> 24)       ] ^
+		rk[1];
+	t[2] =	Td0[(s2      ) & 0xff] ^
+		Td1[(s1 >>  8) & 0xff] ^
+		Td2[(s0 >> 16) & 0xff] ^
+		Td3[(s3 >> 24)       ] ^
+		rk[2];
+	t[3] =	Td0[(s3      ) & 0xff] ^
+		Td1[(s2 >>  8) & 0xff] ^
+		Td2[(s1 >> 16) & 0xff] ^
+		Td3[(s0 >> 24)       ] ^
+		rk[3];
+#endif
+	s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3];
+    }
+    /*
+	 * apply last round and
+	 * map cipher state to byte array block:
+	 */
+	prefetch256(Td4);
+
+	*(u32*)(out+0) =
+		(Td4[(s0      ) & 0xff])	^
+		(Td4[(s3 >>  8) & 0xff] <<  8) ^
+		(Td4[(s2 >> 16) & 0xff] << 16) ^
+		(Td4[(s1 >> 24)       ] << 24) ^
+		rk[0];
+	*(u32*)(out+4) =
+		(Td4[(s1      ) & 0xff])	 ^
+		(Td4[(s0 >>  8) & 0xff] <<  8) ^
+		(Td4[(s3 >> 16) & 0xff] << 16) ^
+		(Td4[(s2 >> 24)       ] << 24) ^
+		rk[1];
+	*(u32*)(out+8) =
+		(Td4[(s2      ) & 0xff])	 ^
+		(Td4[(s1 >>  8) & 0xff] <<  8) ^
+		(Td4[(s0 >> 16) & 0xff] << 16) ^
+		(Td4[(s3 >> 24)       ] << 24) ^
+		rk[2];
+	*(u32*)(out+12) =
+		(Td4[(s3      ) & 0xff])	 ^
+		(Td4[(s2 >>  8) & 0xff] <<  8) ^
+		(Td4[(s1 >> 16) & 0xff] << 16) ^
+		(Td4[(s0 >> 24)       ] << 24) ^
+		rk[3];
+}
diff --git a/crypto/aes/asm/aes-586.pl b/crypto/aes/asm/aes-586.pl
index 89fa261..3bc46a9 100755
--- a/crypto/aes/asm/aes-586.pl
+++ b/crypto/aes/asm/aes-586.pl
@@ -955,8 +955,9 @@
 
     &align	(4);
     &set_label("enc_tail");
-	&push	($key eq "edi" ? $key : "");	# push ivp
+	&mov	($s0,$key eq "edi" ? $key : "");
 	&mov	($key,$_out);			# load out
+	&push	($s0);				# push ivp
 	&mov	($s1,16);
 	&sub	($s1,$s2);
 	&cmp	($key,$acc);			# compare with inp
diff --git a/crypto/aes/asm/aes-armv4.pl b/crypto/aes/asm/aes-armv4.pl
new file mode 100644
index 0000000..15742c1
--- /dev/null
+++ b/crypto/aes/asm/aes-armv4.pl
@@ -0,0 +1,1030 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# AES for ARMv4
+
+# January 2007.
+#
+# Code uses single 1K S-box and is >2 times faster than code generated
+# by gcc-3.4.1. This is thanks to unique feature of ARMv4 ISA, which
+# allows to merge logical or arithmetic operation with shift or rotate
+# in one instruction and emit combined result every cycle. The module
+# is endian-neutral. The performance is ~42 cycles/byte for 128-bit
+# key.
+
+# May 2007.
+#
+# AES_set_[en|de]crypt_key is added.
+
+$s0="r0";
+$s1="r1";
+$s2="r2";
+$s3="r3";
+$t1="r4";
+$t2="r5";
+$t3="r6";
+$i1="r7";
+$i2="r8";
+$i3="r9";
+
+$tbl="r10";
+$key="r11";
+$rounds="r12";
+
+$code=<<___;
+.text
+.code	32
+
+.type	AES_Te,%object
+.align	5
+AES_Te:
+.word	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d
+.word	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554
+.word	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d
+.word	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a
+.word	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87
+.word	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b
+.word	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea
+.word	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b
+.word	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a
+.word	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f
+.word	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108
+.word	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f
+.word	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e
+.word	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5
+.word	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d
+.word	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f
+.word	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e
+.word	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb
+.word	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce
+.word	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497
+.word	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c
+.word	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed
+.word	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b
+.word	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a
+.word	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16
+.word	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594
+.word	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81
+.word	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3
+.word	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a
+.word	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504
+.word	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163
+.word	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d
+.word	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f
+.word	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739
+.word	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47
+.word	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395
+.word	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f
+.word	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883
+.word	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c
+.word	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76
+.word	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e
+.word	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4
+.word	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6
+.word	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b
+.word	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7
+.word	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0
+.word	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25
+.word	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818
+.word	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72
+.word	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651
+.word	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21
+.word	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85
+.word	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa
+.word	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12
+.word	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0
+.word	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9
+.word	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133
+.word	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7
+.word	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920
+.word	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a
+.word	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17
+.word	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8
+.word	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11
+.word	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
+@ Te4[256]
+.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
+.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
+.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
+.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
+.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
+.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
+.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
+.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
+.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
+.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
+.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
+.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
+.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
+.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
+.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
+.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
+.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
+.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
+.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
+.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
+.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
+.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
+.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
+.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
+.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
+.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
+.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
+.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
+.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
+.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
+.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
+.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+@ rcon[]
+.word	0x01000000, 0x02000000, 0x04000000, 0x08000000
+.word	0x10000000, 0x20000000, 0x40000000, 0x80000000
+.word	0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
+.size	AES_Te,.-AES_Te
+
+@ void AES_encrypt(const unsigned char *in, unsigned char *out,
+@ 		 const AES_KEY *key) {
+.global AES_encrypt
+.type   AES_encrypt,%function
+.align	5
+AES_encrypt:
+	sub	r3,pc,#8		@ AES_encrypt
+	stmdb   sp!,{r1,r4-r12,lr}
+	mov	$rounds,r0		@ inp
+	mov	$key,r2
+	sub	$tbl,r3,#AES_encrypt-AES_Te	@ Te
+
+	ldrb	$s0,[$rounds,#3]	@ load input data in endian-neutral
+	ldrb	$t1,[$rounds,#2]	@ manner...
+	ldrb	$t2,[$rounds,#1]
+	ldrb	$t3,[$rounds,#0]
+	orr	$s0,$s0,$t1,lsl#8
+	orr	$s0,$s0,$t2,lsl#16
+	orr	$s0,$s0,$t3,lsl#24
+	ldrb	$s1,[$rounds,#7]
+	ldrb	$t1,[$rounds,#6]
+	ldrb	$t2,[$rounds,#5]
+	ldrb	$t3,[$rounds,#4]
+	orr	$s1,$s1,$t1,lsl#8
+	orr	$s1,$s1,$t2,lsl#16
+	orr	$s1,$s1,$t3,lsl#24
+	ldrb	$s2,[$rounds,#11]
+	ldrb	$t1,[$rounds,#10]
+	ldrb	$t2,[$rounds,#9]
+	ldrb	$t3,[$rounds,#8]
+	orr	$s2,$s2,$t1,lsl#8
+	orr	$s2,$s2,$t2,lsl#16
+	orr	$s2,$s2,$t3,lsl#24
+	ldrb	$s3,[$rounds,#15]
+	ldrb	$t1,[$rounds,#14]
+	ldrb	$t2,[$rounds,#13]
+	ldrb	$t3,[$rounds,#12]
+	orr	$s3,$s3,$t1,lsl#8
+	orr	$s3,$s3,$t2,lsl#16
+	orr	$s3,$s3,$t3,lsl#24
+
+	bl	_armv4_AES_encrypt
+
+	ldr	$rounds,[sp],#4		@ pop out
+	mov	$t1,$s0,lsr#24		@ write output in endian-neutral
+	mov	$t2,$s0,lsr#16		@ manner...
+	mov	$t3,$s0,lsr#8
+	strb	$t1,[$rounds,#0]
+	strb	$t2,[$rounds,#1]
+	strb	$t3,[$rounds,#2]
+	strb	$s0,[$rounds,#3]
+	mov	$t1,$s1,lsr#24
+	mov	$t2,$s1,lsr#16
+	mov	$t3,$s1,lsr#8
+	strb	$t1,[$rounds,#4]
+	strb	$t2,[$rounds,#5]
+	strb	$t3,[$rounds,#6]
+	strb	$s1,[$rounds,#7]
+	mov	$t1,$s2,lsr#24
+	mov	$t2,$s2,lsr#16
+	mov	$t3,$s2,lsr#8
+	strb	$t1,[$rounds,#8]
+	strb	$t2,[$rounds,#9]
+	strb	$t3,[$rounds,#10]
+	strb	$s2,[$rounds,#11]
+	mov	$t1,$s3,lsr#24
+	mov	$t2,$s3,lsr#16
+	mov	$t3,$s3,lsr#8
+	strb	$t1,[$rounds,#12]
+	strb	$t2,[$rounds,#13]
+	strb	$t3,[$rounds,#14]
+	strb	$s3,[$rounds,#15]
+
+	ldmia   sp!,{r4-r12,lr}
+	tst	lr,#1
+	moveq	pc,lr			@ be binary compatible with V4, yet
+	bx	lr			@ interoperable with Thumb ISA:-)
+.size	AES_encrypt,.-AES_encrypt
+
+.type   _armv4_AES_encrypt,%function
+.align	2
+_armv4_AES_encrypt:
+	str	lr,[sp,#-4]!		@ push lr
+	ldr	$t1,[$key],#16
+	ldr	$t2,[$key,#-12]
+	ldr	$t3,[$key,#-8]
+	ldr	$i1,[$key,#-4]
+	ldr	$rounds,[$key,#240-16]
+	eor	$s0,$s0,$t1
+	eor	$s1,$s1,$t2
+	eor	$s2,$s2,$t3
+	eor	$s3,$s3,$i1
+	sub	$rounds,$rounds,#1
+	mov	lr,#255
+
+.Lenc_loop:
+	and	$i2,lr,$s0,lsr#8
+	and	$i3,lr,$s0,lsr#16
+	and	$i1,lr,$s0
+	mov	$s0,$s0,lsr#24
+	ldr	$t1,[$tbl,$i1,lsl#2]	@ Te3[s0>>0]
+	ldr	$s0,[$tbl,$s0,lsl#2]	@ Te0[s0>>24]
+	ldr	$t2,[$tbl,$i2,lsl#2]	@ Te2[s0>>8]
+	ldr	$t3,[$tbl,$i3,lsl#2]	@ Te1[s0>>16]
+
+	and	$i1,lr,$s1,lsr#16	@ i0
+	and	$i2,lr,$s1
+	and	$i3,lr,$s1,lsr#8
+	mov	$s1,$s1,lsr#24
+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Te1[s1>>16]
+	ldr	$s1,[$tbl,$s1,lsl#2]	@ Te0[s1>>24]
+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Te3[s1>>0]
+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Te2[s1>>8]
+	eor	$s0,$s0,$i1,ror#8
+	eor	$s1,$s1,$t1,ror#24
+	eor	$t2,$t2,$i2,ror#8
+	eor	$t3,$t3,$i3,ror#8
+
+	and	$i1,lr,$s2,lsr#8	@ i0
+	and	$i2,lr,$s2,lsr#16	@ i1
+	and	$i3,lr,$s2
+	mov	$s2,$s2,lsr#24
+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Te2[s2>>8]
+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Te1[s2>>16]
+	ldr	$s2,[$tbl,$s2,lsl#2]	@ Te0[s2>>24]
+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Te3[s2>>0]
+	eor	$s0,$s0,$i1,ror#16
+	eor	$s1,$s1,$i2,ror#8
+	eor	$s2,$s2,$t2,ror#16
+	eor	$t3,$t3,$i3,ror#16
+
+	and	$i1,lr,$s3		@ i0
+	and	$i2,lr,$s3,lsr#8	@ i1
+	and	$i3,lr,$s3,lsr#16	@ i2
+	mov	$s3,$s3,lsr#24
+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Te3[s3>>0]
+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Te2[s3>>8]
+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Te1[s3>>16]
+	ldr	$s3,[$tbl,$s3,lsl#2]	@ Te0[s3>>24]
+	eor	$s0,$s0,$i1,ror#24
+	eor	$s1,$s1,$i2,ror#16
+	eor	$s2,$s2,$i3,ror#8
+	eor	$s3,$s3,$t3,ror#8
+
+	ldr	$t1,[$key],#16
+	ldr	$t2,[$key,#-12]
+	ldr	$t3,[$key,#-8]
+	ldr	$i1,[$key,#-4]
+	eor	$s0,$s0,$t1
+	eor	$s1,$s1,$t2
+	eor	$s2,$s2,$t3
+	eor	$s3,$s3,$i1
+
+	subs	$rounds,$rounds,#1
+	bne	.Lenc_loop
+
+	add	$tbl,$tbl,#2
+
+	and	$i1,lr,$s0
+	and	$i2,lr,$s0,lsr#8
+	and	$i3,lr,$s0,lsr#16
+	mov	$s0,$s0,lsr#24
+	ldrb	$t1,[$tbl,$i1,lsl#2]	@ Te4[s0>>0]
+	ldrb	$s0,[$tbl,$s0,lsl#2]	@ Te4[s0>>24]
+	ldrb	$t2,[$tbl,$i2,lsl#2]	@ Te4[s0>>8]
+	ldrb	$t3,[$tbl,$i3,lsl#2]	@ Te4[s0>>16]
+
+	and	$i1,lr,$s1,lsr#16	@ i0
+	and	$i2,lr,$s1
+	and	$i3,lr,$s1,lsr#8
+	mov	$s1,$s1,lsr#24
+	ldrb	$i1,[$tbl,$i1,lsl#2]	@ Te4[s1>>16]
+	ldrb	$s1,[$tbl,$s1,lsl#2]	@ Te4[s1>>24]
+	ldrb	$i2,[$tbl,$i2,lsl#2]	@ Te4[s1>>0]
+	ldrb	$i3,[$tbl,$i3,lsl#2]	@ Te4[s1>>8]
+	eor	$s0,$i1,$s0,lsl#8
+	eor	$s1,$t1,$s1,lsl#24
+	eor	$t2,$i2,$t2,lsl#8
+	eor	$t3,$i3,$t3,lsl#8
+
+	and	$i1,lr,$s2,lsr#8	@ i0
+	and	$i2,lr,$s2,lsr#16	@ i1
+	and	$i3,lr,$s2
+	mov	$s2,$s2,lsr#24
+	ldrb	$i1,[$tbl,$i1,lsl#2]	@ Te4[s2>>8]
+	ldrb	$i2,[$tbl,$i2,lsl#2]	@ Te4[s2>>16]
+	ldrb	$s2,[$tbl,$s2,lsl#2]	@ Te4[s2>>24]
+	ldrb	$i3,[$tbl,$i3,lsl#2]	@ Te4[s2>>0]
+	eor	$s0,$i1,$s0,lsl#8
+	eor	$s1,$s1,$i2,lsl#16
+	eor	$s2,$t2,$s2,lsl#24
+	eor	$t3,$i3,$t3,lsl#8
+
+	and	$i1,lr,$s3		@ i0
+	and	$i2,lr,$s3,lsr#8	@ i1
+	and	$i3,lr,$s3,lsr#16	@ i2
+	mov	$s3,$s3,lsr#24
+	ldrb	$i1,[$tbl,$i1,lsl#2]	@ Te4[s3>>0]
+	ldrb	$i2,[$tbl,$i2,lsl#2]	@ Te4[s3>>8]
+	ldrb	$i3,[$tbl,$i3,lsl#2]	@ Te4[s3>>16]
+	ldrb	$s3,[$tbl,$s3,lsl#2]	@ Te4[s3>>24]
+	eor	$s0,$i1,$s0,lsl#8
+	eor	$s1,$s1,$i2,lsl#8
+	eor	$s2,$s2,$i3,lsl#16
+	eor	$s3,$t3,$s3,lsl#24
+
+	ldr	lr,[sp],#4		@ pop lr
+	ldr	$t1,[$key,#0]
+	ldr	$t2,[$key,#4]
+	ldr	$t3,[$key,#8]
+	ldr	$i1,[$key,#12]
+	eor	$s0,$s0,$t1
+	eor	$s1,$s1,$t2
+	eor	$s2,$s2,$t3
+	eor	$s3,$s3,$i1
+
+	sub	$tbl,$tbl,#2
+	mov	pc,lr			@ return
+.size	_armv4_AES_encrypt,.-_armv4_AES_encrypt
+
+.global AES_set_encrypt_key
+.type   AES_set_encrypt_key,%function
+.align	5
+AES_set_encrypt_key:
+	sub	r3,pc,#8		@ AES_set_encrypt_key
+	teq	r0,#0
+	moveq	r0,#-1
+	beq	.Labrt
+	teq	r2,#0
+	moveq	r0,#-1
+	beq	.Labrt
+
+	teq	r1,#128
+	beq	.Lok
+	teq	r1,#192
+	beq	.Lok
+	teq	r1,#256
+	movne	r0,#-1
+	bne	.Labrt
+
+.Lok:	stmdb   sp!,{r4-r12,lr}
+	sub	$tbl,r3,#AES_set_encrypt_key-AES_Te-1024	@ Te4
+
+	mov	$rounds,r0		@ inp
+	mov	lr,r1			@ bits
+	mov	$key,r2			@ key
+
+	ldrb	$s0,[$rounds,#3]	@ load input data in endian-neutral
+	ldrb	$t1,[$rounds,#2]	@ manner...
+	ldrb	$t2,[$rounds,#1]
+	ldrb	$t3,[$rounds,#0]
+	orr	$s0,$s0,$t1,lsl#8
+	orr	$s0,$s0,$t2,lsl#16
+	orr	$s0,$s0,$t3,lsl#24
+	ldrb	$s1,[$rounds,#7]
+	ldrb	$t1,[$rounds,#6]
+	ldrb	$t2,[$rounds,#5]
+	ldrb	$t3,[$rounds,#4]
+	orr	$s1,$s1,$t1,lsl#8
+	orr	$s1,$s1,$t2,lsl#16
+	orr	$s1,$s1,$t3,lsl#24
+	ldrb	$s2,[$rounds,#11]
+	ldrb	$t1,[$rounds,#10]
+	ldrb	$t2,[$rounds,#9]
+	ldrb	$t3,[$rounds,#8]
+	orr	$s2,$s2,$t1,lsl#8
+	orr	$s2,$s2,$t2,lsl#16
+	orr	$s2,$s2,$t3,lsl#24
+	ldrb	$s3,[$rounds,#15]
+	ldrb	$t1,[$rounds,#14]
+	ldrb	$t2,[$rounds,#13]
+	ldrb	$t3,[$rounds,#12]
+	orr	$s3,$s3,$t1,lsl#8
+	orr	$s3,$s3,$t2,lsl#16
+	orr	$s3,$s3,$t3,lsl#24
+	str	$s0,[$key],#16
+	str	$s1,[$key,#-12]
+	str	$s2,[$key,#-8]
+	str	$s3,[$key,#-4]
+
+	teq	lr,#128
+	bne	.Lnot128
+	mov	$rounds,#10
+	str	$rounds,[$key,#240-16]
+	add	$t3,$tbl,#256			@ rcon
+	mov	lr,#255
+
+.L128_loop:
+	and	$t2,lr,$s3,lsr#24
+	and	$i1,lr,$s3,lsr#16
+	and	$i2,lr,$s3,lsr#8
+	and	$i3,lr,$s3
+	ldrb	$t2,[$tbl,$t2]
+	ldrb	$i1,[$tbl,$i1]
+	ldrb	$i2,[$tbl,$i2]
+	ldrb	$i3,[$tbl,$i3]
+	ldr	$t1,[$t3],#4			@ rcon[i++]
+	orr	$t2,$t2,$i1,lsl#24
+	orr	$t2,$t2,$i2,lsl#16
+	orr	$t2,$t2,$i3,lsl#8
+	eor	$t2,$t2,$t1
+	eor	$s0,$s0,$t2			@ rk[4]=rk[0]^...
+	eor	$s1,$s1,$s0			@ rk[5]=rk[1]^rk[4]
+	eor	$s2,$s2,$s1			@ rk[6]=rk[2]^rk[5]
+	eor	$s3,$s3,$s2			@ rk[7]=rk[3]^rk[6]
+	str	$s0,[$key],#16
+	str	$s1,[$key,#-12]
+	str	$s2,[$key,#-8]
+	str	$s3,[$key,#-4]
+
+	subs	$rounds,$rounds,#1
+	bne	.L128_loop
+	sub	r2,$key,#176
+	b	.Ldone
+
+.Lnot128:
+	ldrb	$i2,[$rounds,#19]
+	ldrb	$t1,[$rounds,#18]
+	ldrb	$t2,[$rounds,#17]
+	ldrb	$t3,[$rounds,#16]
+	orr	$i2,$i2,$t1,lsl#8
+	orr	$i2,$i2,$t2,lsl#16
+	orr	$i2,$i2,$t3,lsl#24
+	ldrb	$i3,[$rounds,#23]
+	ldrb	$t1,[$rounds,#22]
+	ldrb	$t2,[$rounds,#21]
+	ldrb	$t3,[$rounds,#20]
+	orr	$i3,$i3,$t1,lsl#8
+	orr	$i3,$i3,$t2,lsl#16
+	orr	$i3,$i3,$t3,lsl#24
+	str	$i2,[$key],#8
+	str	$i3,[$key,#-4]
+
+	teq	lr,#192
+	bne	.Lnot192
+	mov	$rounds,#12
+	str	$rounds,[$key,#240-24]
+	add	$t3,$tbl,#256			@ rcon
+	mov	lr,#255
+	mov	$rounds,#8
+
+.L192_loop:
+	and	$t2,lr,$i3,lsr#24
+	and	$i1,lr,$i3,lsr#16
+	and	$i2,lr,$i3,lsr#8
+	and	$i3,lr,$i3
+	ldrb	$t2,[$tbl,$t2]
+	ldrb	$i1,[$tbl,$i1]
+	ldrb	$i2,[$tbl,$i2]
+	ldrb	$i3,[$tbl,$i3]
+	ldr	$t1,[$t3],#4			@ rcon[i++]
+	orr	$t2,$t2,$i1,lsl#24
+	orr	$t2,$t2,$i2,lsl#16
+	orr	$t2,$t2,$i3,lsl#8
+	eor	$i3,$t2,$t1
+	eor	$s0,$s0,$i3			@ rk[6]=rk[0]^...
+	eor	$s1,$s1,$s0			@ rk[7]=rk[1]^rk[6]
+	eor	$s2,$s2,$s1			@ rk[8]=rk[2]^rk[7]
+	eor	$s3,$s3,$s2			@ rk[9]=rk[3]^rk[8]
+	str	$s0,[$key],#24
+	str	$s1,[$key,#-20]
+	str	$s2,[$key,#-16]
+	str	$s3,[$key,#-12]
+
+	subs	$rounds,$rounds,#1
+	subeq	r2,$key,#216
+	beq	.Ldone
+
+	ldr	$i1,[$key,#-32]
+	ldr	$i2,[$key,#-28]
+	eor	$i1,$i1,$s3			@ rk[10]=rk[4]^rk[9]
+	eor	$i3,$i2,$i1			@ rk[11]=rk[5]^rk[10]
+	str	$i1,[$key,#-8]
+	str	$i3,[$key,#-4]
+	b	.L192_loop
+
+.Lnot192:
+	ldrb	$i2,[$rounds,#27]
+	ldrb	$t1,[$rounds,#26]
+	ldrb	$t2,[$rounds,#25]
+	ldrb	$t3,[$rounds,#24]
+	orr	$i2,$i2,$t1,lsl#8
+	orr	$i2,$i2,$t2,lsl#16
+	orr	$i2,$i2,$t3,lsl#24
+	ldrb	$i3,[$rounds,#31]
+	ldrb	$t1,[$rounds,#30]
+	ldrb	$t2,[$rounds,#29]
+	ldrb	$t3,[$rounds,#28]
+	orr	$i3,$i3,$t1,lsl#8
+	orr	$i3,$i3,$t2,lsl#16
+	orr	$i3,$i3,$t3,lsl#24
+	str	$i2,[$key],#8
+	str	$i3,[$key,#-4]
+
+	mov	$rounds,#14
+	str	$rounds,[$key,#240-32]
+	add	$t3,$tbl,#256			@ rcon
+	mov	lr,#255
+	mov	$rounds,#7
+
+.L256_loop:
+	and	$t2,lr,$i3,lsr#24
+	and	$i1,lr,$i3,lsr#16
+	and	$i2,lr,$i3,lsr#8
+	and	$i3,lr,$i3
+	ldrb	$t2,[$tbl,$t2]
+	ldrb	$i1,[$tbl,$i1]
+	ldrb	$i2,[$tbl,$i2]
+	ldrb	$i3,[$tbl,$i3]
+	ldr	$t1,[$t3],#4			@ rcon[i++]
+	orr	$t2,$t2,$i1,lsl#24
+	orr	$t2,$t2,$i2,lsl#16
+	orr	$t2,$t2,$i3,lsl#8
+	eor	$i3,$t2,$t1
+	eor	$s0,$s0,$i3			@ rk[8]=rk[0]^...
+	eor	$s1,$s1,$s0			@ rk[9]=rk[1]^rk[8]
+	eor	$s2,$s2,$s1			@ rk[10]=rk[2]^rk[9]
+	eor	$s3,$s3,$s2			@ rk[11]=rk[3]^rk[10]
+	str	$s0,[$key],#32
+	str	$s1,[$key,#-28]
+	str	$s2,[$key,#-24]
+	str	$s3,[$key,#-20]
+
+	subs	$rounds,$rounds,#1
+	subeq	r2,$key,#256
+	beq	.Ldone
+
+	and	$t2,lr,$s3
+	and	$i1,lr,$s3,lsr#8
+	and	$i2,lr,$s3,lsr#16
+	and	$i3,lr,$s3,lsr#24
+	ldrb	$t2,[$tbl,$t2]
+	ldrb	$i1,[$tbl,$i1]
+	ldrb	$i2,[$tbl,$i2]
+	ldrb	$i3,[$tbl,$i3]
+	orr	$t2,$t2,$i1,lsl#8
+	orr	$t2,$t2,$i2,lsl#16
+	orr	$t2,$t2,$i3,lsl#24
+
+	ldr	$t1,[$key,#-48]
+	ldr	$i1,[$key,#-44]
+	ldr	$i2,[$key,#-40]
+	ldr	$i3,[$key,#-36]
+	eor	$t1,$t1,$t2			@ rk[12]=rk[4]^...
+	eor	$i1,$i1,$t1			@ rk[13]=rk[5]^rk[12]
+	eor	$i2,$i2,$i1			@ rk[14]=rk[6]^rk[13]
+	eor	$i3,$i3,$i2			@ rk[15]=rk[7]^rk[14]
+	str	$t1,[$key,#-16]
+	str	$i1,[$key,#-12]
+	str	$i2,[$key,#-8]
+	str	$i3,[$key,#-4]
+	b	.L256_loop
+
+.Ldone:	mov	r0,#0
+	ldmia   sp!,{r4-r12,lr}
+.Labrt:	tst	lr,#1
+	moveq	pc,lr			@ be binary compatible with V4, yet
+	bx	lr			@ interoperable with Thumb ISA:-)
+.size	AES_set_encrypt_key,.-AES_set_encrypt_key
+
+.global AES_set_decrypt_key
+.type   AES_set_decrypt_key,%function
+.align	5
+AES_set_decrypt_key:
+	str	lr,[sp,#-4]!            @ push lr
+	bl	AES_set_encrypt_key
+	teq	r0,#0
+	ldrne	lr,[sp],#4              @ pop lr
+	bne	.Labrt
+
+	stmdb   sp!,{r4-r12}
+
+	ldr	$rounds,[r2,#240]	@ AES_set_encrypt_key preserves r2,
+	mov	$key,r2			@ which is AES_KEY *key
+	mov	$i1,r2
+	add	$i2,r2,$rounds,lsl#4
+
+.Linv:	ldr	$s0,[$i1]
+	ldr	$s1,[$i1,#4]
+	ldr	$s2,[$i1,#8]
+	ldr	$s3,[$i1,#12]
+	ldr	$t1,[$i2]
+	ldr	$t2,[$i2,#4]
+	ldr	$t3,[$i2,#8]
+	ldr	$i3,[$i2,#12]
+	str	$s0,[$i2],#-16
+	str	$s1,[$i2,#16+4]
+	str	$s2,[$i2,#16+8]
+	str	$s3,[$i2,#16+12]
+	str	$t1,[$i1],#16
+	str	$t2,[$i1,#-12]
+	str	$t3,[$i1,#-8]
+	str	$i3,[$i1,#-4]
+	teq	$i1,$i2
+	bne	.Linv
+___
+$mask80=$i1;
+$mask1b=$i2;
+$mask7f=$i3;
+$code.=<<___;
+	ldr	$s0,[$key,#16]!		@ prefetch tp1
+	mov	$mask80,#0x80
+	mov	$mask1b,#0x1b
+	orr	$mask80,$mask80,#0x8000
+	orr	$mask1b,$mask1b,#0x1b00
+	orr	$mask80,$mask80,$mask80,lsl#16
+	orr	$mask1b,$mask1b,$mask1b,lsl#16
+	sub	$rounds,$rounds,#1
+	mvn	$mask7f,$mask80
+	mov	$rounds,$rounds,lsl#2	@ (rounds-1)*4
+
+.Lmix:	and	$t1,$s0,$mask80
+	and	$s1,$s0,$mask7f
+	sub	$t1,$t1,$t1,lsr#7
+	and	$t1,$t1,$mask1b
+	eor	$s1,$t1,$s1,lsl#1	@ tp2
+
+	and	$t1,$s1,$mask80
+	and	$s2,$s1,$mask7f
+	sub	$t1,$t1,$t1,lsr#7
+	and	$t1,$t1,$mask1b
+	eor	$s2,$t1,$s2,lsl#1	@ tp4
+
+	and	$t1,$s2,$mask80
+	and	$s3,$s2,$mask7f
+	sub	$t1,$t1,$t1,lsr#7
+	and	$t1,$t1,$mask1b
+	eor	$s3,$t1,$s3,lsl#1	@ tp8
+
+	eor	$t1,$s1,$s2
+	eor	$t2,$s0,$s3		@ tp9
+	eor	$t1,$t1,$s3		@ tpe
+	eor	$t1,$t1,$s1,ror#24
+	eor	$t1,$t1,$t2,ror#24	@ ^= ROTATE(tpb=tp9^tp2,8)
+	eor	$t1,$t1,$s2,ror#16
+	eor	$t1,$t1,$t2,ror#16	@ ^= ROTATE(tpd=tp9^tp4,16)
+	eor	$t1,$t1,$t2,ror#8	@ ^= ROTATE(tp9,24)
+
+	ldr	$s0,[$key,#4]		@ prefetch tp1
+	str	$t1,[$key],#4
+	subs	$rounds,$rounds,#1
+	bne	.Lmix
+
+	mov	r0,#0
+	ldmia   sp!,{r4-r12,lr}
+	tst	lr,#1
+	moveq	pc,lr			@ be binary compatible with V4, yet
+	bx	lr			@ interoperable with Thumb ISA:-)
+.size	AES_set_decrypt_key,.-AES_set_decrypt_key
+
+.type	AES_Td,%object
+.align	5
+AES_Td:
+.word	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96
+.word	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393
+.word	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25
+.word	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f
+.word	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1
+.word	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6
+.word	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da
+.word	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844
+.word	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd
+.word	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4
+.word	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45
+.word	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94
+.word	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7
+.word	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a
+.word	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5
+.word	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c
+.word	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1
+.word	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a
+.word	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75
+.word	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051
+.word	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46
+.word	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff
+.word	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77
+.word	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb
+.word	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000
+.word	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e
+.word	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927
+.word	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a
+.word	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e
+.word	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16
+.word	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d
+.word	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8
+.word	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd
+.word	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34
+.word	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163
+.word	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120
+.word	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d
+.word	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0
+.word	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422
+.word	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef
+.word	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36
+.word	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4
+.word	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662
+.word	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5
+.word	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3
+.word	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b
+.word	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8
+.word	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6
+.word	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6
+.word	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0
+.word	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815
+.word	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f
+.word	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df
+.word	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f
+.word	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e
+.word	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713
+.word	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89
+.word	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c
+.word	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf
+.word	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86
+.word	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f
+.word	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541
+.word	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190
+.word	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
+@ Td4[256]
+.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
+.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
+.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
+.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
+.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
+.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
+.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
+.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
+.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
+.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
+.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
+.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
+.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
+.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
+.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
+.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
+.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+.size	AES_Td,.-AES_Td
+
+@ void AES_decrypt(const unsigned char *in, unsigned char *out,
+@ 		 const AES_KEY *key) {
+.global AES_decrypt
+.type   AES_decrypt,%function
+.align	5
+AES_decrypt:
+	sub	r3,pc,#8		@ AES_decrypt
+	stmdb   sp!,{r1,r4-r12,lr}
+	mov	$rounds,r0		@ inp
+	mov	$key,r2
+	sub	$tbl,r3,#AES_decrypt-AES_Td		@ Td
+
+	ldrb	$s0,[$rounds,#3]	@ load input data in endian-neutral
+	ldrb	$t1,[$rounds,#2]	@ manner...
+	ldrb	$t2,[$rounds,#1]
+	ldrb	$t3,[$rounds,#0]
+	orr	$s0,$s0,$t1,lsl#8
+	orr	$s0,$s0,$t2,lsl#16
+	orr	$s0,$s0,$t3,lsl#24
+	ldrb	$s1,[$rounds,#7]
+	ldrb	$t1,[$rounds,#6]
+	ldrb	$t2,[$rounds,#5]
+	ldrb	$t3,[$rounds,#4]
+	orr	$s1,$s1,$t1,lsl#8
+	orr	$s1,$s1,$t2,lsl#16
+	orr	$s1,$s1,$t3,lsl#24
+	ldrb	$s2,[$rounds,#11]
+	ldrb	$t1,[$rounds,#10]
+	ldrb	$t2,[$rounds,#9]
+	ldrb	$t3,[$rounds,#8]
+	orr	$s2,$s2,$t1,lsl#8
+	orr	$s2,$s2,$t2,lsl#16
+	orr	$s2,$s2,$t3,lsl#24
+	ldrb	$s3,[$rounds,#15]
+	ldrb	$t1,[$rounds,#14]
+	ldrb	$t2,[$rounds,#13]
+	ldrb	$t3,[$rounds,#12]
+	orr	$s3,$s3,$t1,lsl#8
+	orr	$s3,$s3,$t2,lsl#16
+	orr	$s3,$s3,$t3,lsl#24
+
+	bl	_armv4_AES_decrypt
+
+	ldr	$rounds,[sp],#4		@ pop out
+	mov	$t1,$s0,lsr#24		@ write output in endian-neutral
+	mov	$t2,$s0,lsr#16		@ manner...
+	mov	$t3,$s0,lsr#8
+	strb	$t1,[$rounds,#0]
+	strb	$t2,[$rounds,#1]
+	strb	$t3,[$rounds,#2]
+	strb	$s0,[$rounds,#3]
+	mov	$t1,$s1,lsr#24
+	mov	$t2,$s1,lsr#16
+	mov	$t3,$s1,lsr#8
+	strb	$t1,[$rounds,#4]
+	strb	$t2,[$rounds,#5]
+	strb	$t3,[$rounds,#6]
+	strb	$s1,[$rounds,#7]
+	mov	$t1,$s2,lsr#24
+	mov	$t2,$s2,lsr#16
+	mov	$t3,$s2,lsr#8
+	strb	$t1,[$rounds,#8]
+	strb	$t2,[$rounds,#9]
+	strb	$t3,[$rounds,#10]
+	strb	$s2,[$rounds,#11]
+	mov	$t1,$s3,lsr#24
+	mov	$t2,$s3,lsr#16
+	mov	$t3,$s3,lsr#8
+	strb	$t1,[$rounds,#12]
+	strb	$t2,[$rounds,#13]
+	strb	$t3,[$rounds,#14]
+	strb	$s3,[$rounds,#15]
+
+	ldmia   sp!,{r4-r12,lr}
+	tst	lr,#1
+	moveq	pc,lr			@ be binary compatible with V4, yet
+	bx	lr			@ interoperable with Thumb ISA:-)
+.size	AES_decrypt,.-AES_decrypt
+
+.type   _armv4_AES_decrypt,%function
+.align	2
+_armv4_AES_decrypt:
+	str	lr,[sp,#-4]!		@ push lr
+	ldr	$t1,[$key],#16
+	ldr	$t2,[$key,#-12]
+	ldr	$t3,[$key,#-8]
+	ldr	$i1,[$key,#-4]
+	ldr	$rounds,[$key,#240-16]
+	eor	$s0,$s0,$t1
+	eor	$s1,$s1,$t2
+	eor	$s2,$s2,$t3
+	eor	$s3,$s3,$i1
+	sub	$rounds,$rounds,#1
+	mov	lr,#255
+
+.Ldec_loop:
+	and	$i1,lr,$s0,lsr#16
+	and	$i2,lr,$s0,lsr#8
+	and	$i3,lr,$s0
+	mov	$s0,$s0,lsr#24
+	ldr	$t1,[$tbl,$i1,lsl#2]	@ Td1[s0>>16]
+	ldr	$s0,[$tbl,$s0,lsl#2]	@ Td0[s0>>24]
+	ldr	$t2,[$tbl,$i2,lsl#2]	@ Td2[s0>>8]
+	ldr	$t3,[$tbl,$i3,lsl#2]	@ Td3[s0>>0]
+
+	and	$i1,lr,$s1		@ i0
+	and	$i2,lr,$s1,lsr#16
+	and	$i3,lr,$s1,lsr#8
+	mov	$s1,$s1,lsr#24
+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Td3[s1>>0]
+	ldr	$s1,[$tbl,$s1,lsl#2]	@ Td0[s1>>24]
+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Td1[s1>>16]
+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Td2[s1>>8]
+	eor	$s0,$s0,$i1,ror#24
+	eor	$s1,$s1,$t1,ror#8
+	eor	$t2,$i2,$t2,ror#8
+	eor	$t3,$i3,$t3,ror#8
+
+	and	$i1,lr,$s2,lsr#8	@ i0
+	and	$i2,lr,$s2		@ i1
+	and	$i3,lr,$s2,lsr#16
+	mov	$s2,$s2,lsr#24
+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Td2[s2>>8]
+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Td3[s2>>0]
+	ldr	$s2,[$tbl,$s2,lsl#2]	@ Td0[s2>>24]
+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Td1[s2>>16]
+	eor	$s0,$s0,$i1,ror#16
+	eor	$s1,$s1,$i2,ror#24
+	eor	$s2,$s2,$t2,ror#8
+	eor	$t3,$i3,$t3,ror#8
+
+	and	$i1,lr,$s3,lsr#16	@ i0
+	and	$i2,lr,$s3,lsr#8	@ i1
+	and	$i3,lr,$s3		@ i2
+	mov	$s3,$s3,lsr#24
+	ldr	$i1,[$tbl,$i1,lsl#2]	@ Td1[s3>>16]
+	ldr	$i2,[$tbl,$i2,lsl#2]	@ Td2[s3>>8]
+	ldr	$i3,[$tbl,$i3,lsl#2]	@ Td3[s3>>0]
+	ldr	$s3,[$tbl,$s3,lsl#2]	@ Td0[s3>>24]
+	eor	$s0,$s0,$i1,ror#8
+	eor	$s1,$s1,$i2,ror#16
+	eor	$s2,$s2,$i3,ror#24
+	eor	$s3,$s3,$t3,ror#8
+
+	ldr	$t1,[$key],#16
+	ldr	$t2,[$key,#-12]
+	ldr	$t3,[$key,#-8]
+	ldr	$i1,[$key,#-4]
+	eor	$s0,$s0,$t1
+	eor	$s1,$s1,$t2
+	eor	$s2,$s2,$t3
+	eor	$s3,$s3,$i1
+
+	subs	$rounds,$rounds,#1
+	bne	.Ldec_loop
+
+	add	$tbl,$tbl,#1024
+
+	ldr	$t1,[$tbl,#0]		@ prefetch Td4
+	ldr	$t2,[$tbl,#32]
+	ldr	$t3,[$tbl,#64]
+	ldr	$i1,[$tbl,#96]
+	ldr	$i2,[$tbl,#128]
+	ldr	$i3,[$tbl,#160]
+	ldr	$t1,[$tbl,#192]
+	ldr	$t2,[$tbl,#224]
+
+	and	$i1,lr,$s0,lsr#16
+	and	$i2,lr,$s0,lsr#8
+	and	$i3,lr,$s0
+	ldrb	$s0,[$tbl,$s0,lsr#24]	@ Td4[s0>>24]
+	ldrb	$t1,[$tbl,$i1]		@ Td4[s0>>16]
+	ldrb	$t2,[$tbl,$i2]		@ Td4[s0>>8]
+	ldrb	$t3,[$tbl,$i3]		@ Td4[s0>>0]
+
+	and	$i1,lr,$s1		@ i0
+	and	$i2,lr,$s1,lsr#16
+	and	$i3,lr,$s1,lsr#8
+	ldrb	$i1,[$tbl,$i1]		@ Td4[s1>>0]
+	ldrb	$s1,[$tbl,$s1,lsr#24]	@ Td4[s1>>24]
+	ldrb	$i2,[$tbl,$i2]		@ Td4[s1>>16]
+	ldrb	$i3,[$tbl,$i3]		@ Td4[s1>>8]
+	eor	$s0,$i1,$s0,lsl#24
+	eor	$s1,$t1,$s1,lsl#8
+	eor	$t2,$t2,$i2,lsl#8
+	eor	$t3,$t3,$i3,lsl#8
+
+	and	$i1,lr,$s2,lsr#8	@ i0
+	and	$i2,lr,$s2		@ i1
+	and	$i3,lr,$s2,lsr#16
+	ldrb	$i1,[$tbl,$i1]		@ Td4[s2>>8]
+	ldrb	$i2,[$tbl,$i2]		@ Td4[s2>>0]
+	ldrb	$s2,[$tbl,$s2,lsr#24]	@ Td4[s2>>24]
+	ldrb	$i3,[$tbl,$i3]		@ Td4[s2>>16]
+	eor	$s0,$s0,$i1,lsl#8
+	eor	$s1,$i2,$s1,lsl#16
+	eor	$s2,$t2,$s2,lsl#16
+	eor	$t3,$t3,$i3,lsl#16
+
+	and	$i1,lr,$s3,lsr#16	@ i0
+	and	$i2,lr,$s3,lsr#8	@ i1
+	and	$i3,lr,$s3		@ i2
+	ldrb	$i1,[$tbl,$i1]		@ Td4[s3>>16]
+	ldrb	$i2,[$tbl,$i2]		@ Td4[s3>>8]
+	ldrb	$i3,[$tbl,$i3]		@ Td4[s3>>0]
+	ldrb	$s3,[$tbl,$s3,lsr#24]	@ Td4[s3>>24]
+	eor	$s0,$s0,$i1,lsl#16
+	eor	$s1,$s1,$i2,lsl#8
+	eor	$s2,$i3,$s2,lsl#8
+	eor	$s3,$t3,$s3,lsl#24
+
+	ldr	lr,[sp],#4		@ pop lr
+	ldr	$t1,[$key,#0]
+	ldr	$t2,[$key,#4]
+	ldr	$t3,[$key,#8]
+	ldr	$i1,[$key,#12]
+	eor	$s0,$s0,$t1
+	eor	$s1,$s1,$t2
+	eor	$s2,$s2,$t3
+	eor	$s3,$s3,$i1
+
+	sub	$tbl,$tbl,#1024
+	mov	pc,lr			@ return
+.size	_armv4_AES_decrypt,.-_armv4_AES_decrypt
+.asciz	"AES for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
+print $code;
diff --git a/crypto/aes/asm/aes-ppc.pl b/crypto/aes/asm/aes-ppc.pl
new file mode 100644
index 0000000..ce42765
--- /dev/null
+++ b/crypto/aes/asm/aes-ppc.pl
@@ -0,0 +1,1176 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# Needs more work: key setup, page boundaries, CBC routine...
+#
+# ppc_AES_[en|de]crypt perform at 18 cycles per byte processed with
+# 128-bit key, which is ~40% better than 64-bit code generated by gcc
+# 4.0. But these are not the ones currently used! Their "compact"
+# counterparts are, for security reason. ppc_AES_encrypt_compact runs
+# at 1/2 of ppc_AES_encrypt speed, while ppc_AES_decrypt_compact -
+# at 1/3 of ppc_AES_decrypt.
+
+$flavour = shift;
+
+if ($flavour =~ /64/) {
+	$SIZE_T	=8;
+	$STU	="stdu";
+	$POP	="ld";
+	$PUSH	="std";
+} elsif ($flavour =~ /32/) {
+	$SIZE_T	=4;
+	$STU	="stwu";
+	$POP	="lwz";
+	$PUSH	="stw";
+} else { die "nonsense $flavour"; }
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
+die "can't locate ppc-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
+
+$FRAME=32*$SIZE_T;
+
+sub _data_word()
+{ my $i;
+    while(defined($i=shift)) { $code.=sprintf"\t.long\t0x%08x,0x%08x\n",$i,$i; }
+}
+
+$sp="r1";
+$toc="r2";
+$inp="r3";
+$out="r4";
+$key="r5";
+
+$Tbl0="r3";
+$Tbl1="r6";
+$Tbl2="r7";
+$Tbl3="r2";
+
+$s0="r8";
+$s1="r9";
+$s2="r10";
+$s3="r11";
+
+$t0="r12";
+$t1="r13";
+$t2="r14";
+$t3="r15";
+
+$acc00="r16";
+$acc01="r17";
+$acc02="r18";
+$acc03="r19";
+
+$acc04="r20";
+$acc05="r21";
+$acc06="r22";
+$acc07="r23";
+
+$acc08="r24";
+$acc09="r25";
+$acc10="r26";
+$acc11="r27";
+
+$acc12="r28";
+$acc13="r29";
+$acc14="r30";
+$acc15="r31";
+
+# stay away from TLS pointer
+if ($SIZE_T==8)	{ die if ($t1 ne "r13");  $t1="r0";		}
+else		{ die if ($Tbl3 ne "r2"); $Tbl3=$t0; $t0="r0";	}
+$mask80=$Tbl2;
+$mask1b=$Tbl3;
+
+$code.=<<___;
+.machine	"any"
+.text
+
+.align	7
+LAES_Te:
+	mflr	r0
+	bcl	20,31,\$+4
+	mflr	$Tbl0	;    vvvvv "distance" between . and 1st data entry
+	addi	$Tbl0,$Tbl0,`128-8`
+	mtlr	r0
+	blr
+	.space	`32-24`
+LAES_Td:
+	mflr	r0
+	bcl	20,31,\$+4
+	mflr	$Tbl0	;    vvvvvvvv "distance" between . and 1st data entry
+	addi	$Tbl0,$Tbl0,`128-8-32+2048+256`
+	mtlr	r0
+	blr
+	.space	`128-32-24`
+___
+&_data_word(
+	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
+	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
+	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
+	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
+	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
+	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
+	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
+	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
+	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
+	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
+	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
+	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
+	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
+	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
+	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
+	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
+	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
+	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
+	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
+	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
+	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
+	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
+	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
+	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
+	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
+	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
+	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
+	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
+	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
+	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
+	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
+	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
+	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
+	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
+	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
+	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
+	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
+	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
+	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
+	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
+	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
+	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
+	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
+	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
+	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
+	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
+	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
+	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
+	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
+	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
+	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
+	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
+	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
+	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
+	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
+	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
+	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
+	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
+	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
+	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
+	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
+	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
+	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
+	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
+$code.=<<___;
+.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
+.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
+.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
+.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
+.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
+.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
+.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
+.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
+.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
+.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
+.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
+.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
+.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
+.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
+.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
+.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
+.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
+.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
+.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
+.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
+.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
+.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
+.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
+.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
+.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
+.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
+.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
+.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
+.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
+.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
+.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
+.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+___
+&_data_word(
+	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
+	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
+	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
+	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
+	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
+	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
+	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
+	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
+	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
+	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
+	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
+	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
+	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
+	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
+	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
+	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
+	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
+	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
+	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
+	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
+	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
+	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
+	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
+	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
+	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
+	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
+	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
+	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
+	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
+	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
+	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
+	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
+	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
+	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
+	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
+	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
+	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
+	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
+	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
+	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
+	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
+	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
+	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
+	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
+	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
+	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
+	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
+	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
+	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
+	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
+	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
+	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
+	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
+	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
+	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
+	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
+	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
+	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
+	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
+	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
+	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
+	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
+	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
+	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
+$code.=<<___;
+.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
+.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
+.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
+.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
+.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
+.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
+.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
+.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
+.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
+.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
+.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
+.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
+.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
+.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
+.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
+.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
+.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+
+
+.globl	.AES_encrypt
+.align	7
+.AES_encrypt:
+	mflr	r0
+	$STU	$sp,-$FRAME($sp)
+
+	$PUSH	r0,`$FRAME-$SIZE_T*21`($sp)
+	$PUSH	$toc,`$FRAME-$SIZE_T*20`($sp)
+	$PUSH	r13,`$FRAME-$SIZE_T*19`($sp)
+	$PUSH	r14,`$FRAME-$SIZE_T*18`($sp)
+	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
+	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
+	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
+	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
+	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
+	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
+	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
+	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
+	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
+	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
+	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
+	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
+	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
+	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
+	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
+	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
+	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
+
+	lwz	$s0,0($inp)
+	lwz	$s1,4($inp)
+	lwz	$s2,8($inp)
+	lwz	$s3,12($inp)
+	bl	LAES_Te
+	bl	Lppc_AES_encrypt_compact
+	stw	$s0,0($out)
+	stw	$s1,4($out)
+	stw	$s2,8($out)
+	stw	$s3,12($out)
+
+	$POP	r0,`$FRAME-$SIZE_T*21`($sp)
+	$POP	$toc,`$FRAME-$SIZE_T*20`($sp)
+	$POP	r13,`$FRAME-$SIZE_T*19`($sp)
+	$POP	r14,`$FRAME-$SIZE_T*18`($sp)
+	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
+	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
+	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
+	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
+	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
+	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
+	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
+	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
+	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
+	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
+	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
+	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
+	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
+	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
+	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
+	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
+	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
+	mtlr	r0
+	addi	$sp,$sp,$FRAME
+	blr
+
+.align	4
+Lppc_AES_encrypt:
+	lwz	$acc00,240($key)
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	addi	$Tbl1,$Tbl0,3
+	addi	$Tbl2,$Tbl0,2
+	addi	$Tbl3,$Tbl0,1
+	addi	$acc00,$acc00,-1
+	addi	$key,$key,16
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	mtctr	$acc00
+.align	4
+Lenc_loop:
+	rlwinm	$acc00,$s0,`32-24+3`,21,28
+	rlwinm	$acc01,$s1,`32-24+3`,21,28
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	rlwinm	$acc02,$s2,`32-24+3`,21,28
+	rlwinm	$acc03,$s3,`32-24+3`,21,28
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	rlwinm	$acc04,$s1,`32-16+3`,21,28
+	rlwinm	$acc05,$s2,`32-16+3`,21,28
+	lwzx	$acc00,$Tbl0,$acc00
+	lwzx	$acc01,$Tbl0,$acc01
+	rlwinm	$acc06,$s3,`32-16+3`,21,28
+	rlwinm	$acc07,$s0,`32-16+3`,21,28
+	lwzx	$acc02,$Tbl0,$acc02
+	lwzx	$acc03,$Tbl0,$acc03
+	rlwinm	$acc08,$s2,`32-8+3`,21,28
+	rlwinm	$acc09,$s3,`32-8+3`,21,28
+	lwzx	$acc04,$Tbl1,$acc04
+	lwzx	$acc05,$Tbl1,$acc05
+	rlwinm	$acc10,$s0,`32-8+3`,21,28
+	rlwinm	$acc11,$s1,`32-8+3`,21,28
+	lwzx	$acc06,$Tbl1,$acc06
+	lwzx	$acc07,$Tbl1,$acc07
+	rlwinm	$acc12,$s3,`0+3`,21,28
+	rlwinm	$acc13,$s0,`0+3`,21,28
+	lwzx	$acc08,$Tbl2,$acc08
+	lwzx	$acc09,$Tbl2,$acc09
+	rlwinm	$acc14,$s1,`0+3`,21,28
+	rlwinm	$acc15,$s2,`0+3`,21,28
+	lwzx	$acc10,$Tbl2,$acc10
+	lwzx	$acc11,$Tbl2,$acc11
+	xor	$t0,$t0,$acc00
+	xor	$t1,$t1,$acc01
+	lwzx	$acc12,$Tbl3,$acc12
+	lwzx	$acc13,$Tbl3,$acc13
+	xor	$t2,$t2,$acc02
+	xor	$t3,$t3,$acc03
+	lwzx	$acc14,$Tbl3,$acc14
+	lwzx	$acc15,$Tbl3,$acc15
+	xor	$t0,$t0,$acc04
+	xor	$t1,$t1,$acc05
+	xor	$t2,$t2,$acc06
+	xor	$t3,$t3,$acc07
+	xor	$t0,$t0,$acc08
+	xor	$t1,$t1,$acc09
+	xor	$t2,$t2,$acc10
+	xor	$t3,$t3,$acc11
+	xor	$s0,$t0,$acc12
+	xor	$s1,$t1,$acc13
+	xor	$s2,$t2,$acc14
+	xor	$s3,$t3,$acc15
+	addi	$key,$key,16
+	bdnz-	Lenc_loop
+
+	addi	$Tbl2,$Tbl0,2048
+	nop
+	lwz	$acc08,`2048+0`($Tbl0)	! prefetch Te4
+	lwz	$acc09,`2048+32`($Tbl0)
+	lwz	$acc10,`2048+64`($Tbl0)
+	lwz	$acc11,`2048+96`($Tbl0)
+	lwz	$acc08,`2048+128`($Tbl0)
+	lwz	$acc09,`2048+160`($Tbl0)
+	lwz	$acc10,`2048+192`($Tbl0)
+	lwz	$acc11,`2048+224`($Tbl0)
+	rlwinm	$acc00,$s0,`32-24`,24,31
+	rlwinm	$acc01,$s1,`32-24`,24,31
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	rlwinm	$acc02,$s2,`32-24`,24,31
+	rlwinm	$acc03,$s3,`32-24`,24,31
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	rlwinm	$acc04,$s1,`32-16`,24,31
+	rlwinm	$acc05,$s2,`32-16`,24,31
+	lbzx	$acc00,$Tbl2,$acc00
+	lbzx	$acc01,$Tbl2,$acc01
+	rlwinm	$acc06,$s3,`32-16`,24,31
+	rlwinm	$acc07,$s0,`32-16`,24,31
+	lbzx	$acc02,$Tbl2,$acc02
+	lbzx	$acc03,$Tbl2,$acc03
+	rlwinm	$acc08,$s2,`32-8`,24,31
+	rlwinm	$acc09,$s3,`32-8`,24,31
+	lbzx	$acc04,$Tbl2,$acc04
+	lbzx	$acc05,$Tbl2,$acc05
+	rlwinm	$acc10,$s0,`32-8`,24,31
+	rlwinm	$acc11,$s1,`32-8`,24,31
+	lbzx	$acc06,$Tbl2,$acc06
+	lbzx	$acc07,$Tbl2,$acc07
+	rlwinm	$acc12,$s3,`0`,24,31
+	rlwinm	$acc13,$s0,`0`,24,31
+	lbzx	$acc08,$Tbl2,$acc08
+	lbzx	$acc09,$Tbl2,$acc09
+	rlwinm	$acc14,$s1,`0`,24,31
+	rlwinm	$acc15,$s2,`0`,24,31
+	lbzx	$acc10,$Tbl2,$acc10
+	lbzx	$acc11,$Tbl2,$acc11
+	rlwinm	$s0,$acc00,24,0,7
+	rlwinm	$s1,$acc01,24,0,7
+	lbzx	$acc12,$Tbl2,$acc12
+	lbzx	$acc13,$Tbl2,$acc13
+	rlwinm	$s2,$acc02,24,0,7
+	rlwinm	$s3,$acc03,24,0,7
+	lbzx	$acc14,$Tbl2,$acc14
+	lbzx	$acc15,$Tbl2,$acc15
+	rlwimi	$s0,$acc04,16,8,15
+	rlwimi	$s1,$acc05,16,8,15
+	rlwimi	$s2,$acc06,16,8,15
+	rlwimi	$s3,$acc07,16,8,15
+	rlwimi	$s0,$acc08,8,16,23
+	rlwimi	$s1,$acc09,8,16,23
+	rlwimi	$s2,$acc10,8,16,23
+	rlwimi	$s3,$acc11,8,16,23
+	or	$s0,$s0,$acc12
+	or	$s1,$s1,$acc13
+	or	$s2,$s2,$acc14
+	or	$s3,$s3,$acc15
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	blr
+
+.align	4
+Lppc_AES_encrypt_compact:
+	lwz	$acc00,240($key)
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	addi	$Tbl1,$Tbl0,2048
+	lis	$mask80,0x8080
+	lis	$mask1b,0x1b1b
+	addi	$key,$key,16
+	ori	$mask80,$mask80,0x8080
+	ori	$mask1b,$mask1b,0x1b1b
+	mtctr	$acc00
+.align	4
+Lenc_compact_loop:
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	rlwinm	$acc00,$s0,`32-24`,24,31
+	rlwinm	$acc01,$s1,`32-24`,24,31
+	rlwinm	$acc02,$s2,`32-24`,24,31
+	rlwinm	$acc03,$s3,`32-24`,24,31
+	lbzx	$acc00,$Tbl1,$acc00
+	lbzx	$acc01,$Tbl1,$acc01
+	rlwinm	$acc04,$s1,`32-16`,24,31
+	rlwinm	$acc05,$s2,`32-16`,24,31
+	lbzx	$acc02,$Tbl1,$acc02
+	lbzx	$acc03,$Tbl1,$acc03
+	rlwinm	$acc06,$s3,`32-16`,24,31
+	rlwinm	$acc07,$s0,`32-16`,24,31
+	lbzx	$acc04,$Tbl1,$acc04
+	lbzx	$acc05,$Tbl1,$acc05
+	rlwinm	$acc08,$s2,`32-8`,24,31
+	rlwinm	$acc09,$s3,`32-8`,24,31
+	lbzx	$acc06,$Tbl1,$acc06
+	lbzx	$acc07,$Tbl1,$acc07
+	rlwinm	$acc10,$s0,`32-8`,24,31
+	rlwinm	$acc11,$s1,`32-8`,24,31
+	lbzx	$acc08,$Tbl1,$acc08
+	lbzx	$acc09,$Tbl1,$acc09
+	rlwinm	$acc12,$s3,`0`,24,31
+	rlwinm	$acc13,$s0,`0`,24,31
+	lbzx	$acc10,$Tbl1,$acc10
+	lbzx	$acc11,$Tbl1,$acc11
+	rlwinm	$acc14,$s1,`0`,24,31
+	rlwinm	$acc15,$s2,`0`,24,31
+	lbzx	$acc12,$Tbl1,$acc12
+	lbzx	$acc13,$Tbl1,$acc13
+	rlwinm	$s0,$acc00,24,0,7
+	rlwinm	$s1,$acc01,24,0,7
+	lbzx	$acc14,$Tbl1,$acc14
+	lbzx	$acc15,$Tbl1,$acc15
+	rlwinm	$s2,$acc02,24,0,7
+	rlwinm	$s3,$acc03,24,0,7
+	rlwimi	$s0,$acc04,16,8,15
+	rlwimi	$s1,$acc05,16,8,15
+	rlwimi	$s2,$acc06,16,8,15
+	rlwimi	$s3,$acc07,16,8,15
+	rlwimi	$s0,$acc08,8,16,23
+	rlwimi	$s1,$acc09,8,16,23
+	rlwimi	$s2,$acc10,8,16,23
+	rlwimi	$s3,$acc11,8,16,23
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	or	$s0,$s0,$acc12
+	or	$s1,$s1,$acc13
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	or	$s2,$s2,$acc14
+	or	$s3,$s3,$acc15
+
+	addi	$key,$key,16
+	bdz	Lenc_compact_done
+
+	and	$acc00,$s0,$mask80	# r1=r0&0x80808080
+	and	$acc01,$s1,$mask80
+	and	$acc02,$s2,$mask80
+	and	$acc03,$s3,$mask80
+	srwi	$acc04,$acc00,7		# r1>>7
+	srwi	$acc05,$acc01,7
+	srwi	$acc06,$acc02,7
+	srwi	$acc07,$acc03,7
+	andc	$acc08,$s0,$mask80	# r0&0x7f7f7f7f
+	andc	$acc09,$s1,$mask80
+	andc	$acc10,$s2,$mask80
+	andc	$acc11,$s3,$mask80
+	sub	$acc00,$acc00,$acc04	# r1-(r1>>7)
+	sub	$acc01,$acc01,$acc05
+	sub	$acc02,$acc02,$acc06
+	sub	$acc03,$acc03,$acc07
+	add	$acc08,$acc08,$acc08	# (r0&0x7f7f7f7f)<<1
+	add	$acc09,$acc09,$acc09
+	add	$acc10,$acc10,$acc10
+	add	$acc11,$acc11,$acc11
+	and	$acc00,$acc00,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc01,$acc01,$mask1b
+	and	$acc02,$acc02,$mask1b
+	and	$acc03,$acc03,$mask1b
+	xor	$acc00,$acc00,$acc08	# r2
+	xor	$acc01,$acc01,$acc09
+	xor	$acc02,$acc02,$acc10
+	xor	$acc03,$acc03,$acc11
+
+	rotlwi	$acc12,$s0,16		# ROTATE(r0,16)
+	rotlwi	$acc13,$s1,16
+	rotlwi	$acc14,$s2,16
+	rotlwi	$acc15,$s3,16
+	xor	$s0,$s0,$acc00		# r0^r2
+	xor	$s1,$s1,$acc01
+	xor	$s2,$s2,$acc02
+	xor	$s3,$s3,$acc03
+	rotrwi	$s0,$s0,24		# ROTATE(r2^r0,24)
+	rotrwi	$s1,$s1,24
+	rotrwi	$s2,$s2,24
+	rotrwi	$s3,$s3,24
+	xor	$s0,$s0,$acc00		# ROTATE(r2^r0,24)^r2
+	xor	$s1,$s1,$acc01
+	xor	$s2,$s2,$acc02
+	xor	$s3,$s3,$acc03
+	rotlwi	$acc08,$acc12,8		# ROTATE(r0,24)
+	rotlwi	$acc09,$acc13,8
+	rotlwi	$acc10,$acc14,8
+	rotlwi	$acc11,$acc15,8
+	xor	$s0,$s0,$acc12		#
+	xor	$s1,$s1,$acc13
+	xor	$s2,$s2,$acc14
+	xor	$s3,$s3,$acc15
+	xor	$s0,$s0,$acc08		#
+	xor	$s1,$s1,$acc09
+	xor	$s2,$s2,$acc10
+	xor	$s3,$s3,$acc11
+
+	b	Lenc_compact_loop
+.align	4
+Lenc_compact_done:
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	blr
+
+.globl	.AES_decrypt
+.align	7
+.AES_decrypt:
+	mflr	r0
+	$STU	$sp,-$FRAME($sp)
+
+	$PUSH	r0,`$FRAME-$SIZE_T*21`($sp)
+	$PUSH	$toc,`$FRAME-$SIZE_T*20`($sp)
+	$PUSH	r13,`$FRAME-$SIZE_T*19`($sp)
+	$PUSH	r14,`$FRAME-$SIZE_T*18`($sp)
+	$PUSH	r15,`$FRAME-$SIZE_T*17`($sp)
+	$PUSH	r16,`$FRAME-$SIZE_T*16`($sp)
+	$PUSH	r17,`$FRAME-$SIZE_T*15`($sp)
+	$PUSH	r18,`$FRAME-$SIZE_T*14`($sp)
+	$PUSH	r19,`$FRAME-$SIZE_T*13`($sp)
+	$PUSH	r20,`$FRAME-$SIZE_T*12`($sp)
+	$PUSH	r21,`$FRAME-$SIZE_T*11`($sp)
+	$PUSH	r22,`$FRAME-$SIZE_T*10`($sp)
+	$PUSH	r23,`$FRAME-$SIZE_T*9`($sp)
+	$PUSH	r24,`$FRAME-$SIZE_T*8`($sp)
+	$PUSH	r25,`$FRAME-$SIZE_T*7`($sp)
+	$PUSH	r26,`$FRAME-$SIZE_T*6`($sp)
+	$PUSH	r27,`$FRAME-$SIZE_T*5`($sp)
+	$PUSH	r28,`$FRAME-$SIZE_T*4`($sp)
+	$PUSH	r29,`$FRAME-$SIZE_T*3`($sp)
+	$PUSH	r30,`$FRAME-$SIZE_T*2`($sp)
+	$PUSH	r31,`$FRAME-$SIZE_T*1`($sp)
+
+	lwz	$s0,0($inp)
+	lwz	$s1,4($inp)
+	lwz	$s2,8($inp)
+	lwz	$s3,12($inp)
+	bl	LAES_Td
+	bl	Lppc_AES_decrypt_compact
+	stw	$s0,0($out)
+	stw	$s1,4($out)
+	stw	$s2,8($out)
+	stw	$s3,12($out)
+
+	$POP	r0,`$FRAME-$SIZE_T*21`($sp)
+	$POP	$toc,`$FRAME-$SIZE_T*20`($sp)
+	$POP	r13,`$FRAME-$SIZE_T*19`($sp)
+	$POP	r14,`$FRAME-$SIZE_T*18`($sp)
+	$POP	r15,`$FRAME-$SIZE_T*17`($sp)
+	$POP	r16,`$FRAME-$SIZE_T*16`($sp)
+	$POP	r17,`$FRAME-$SIZE_T*15`($sp)
+	$POP	r18,`$FRAME-$SIZE_T*14`($sp)
+	$POP	r19,`$FRAME-$SIZE_T*13`($sp)
+	$POP	r20,`$FRAME-$SIZE_T*12`($sp)
+	$POP	r21,`$FRAME-$SIZE_T*11`($sp)
+	$POP	r22,`$FRAME-$SIZE_T*10`($sp)
+	$POP	r23,`$FRAME-$SIZE_T*9`($sp)
+	$POP	r24,`$FRAME-$SIZE_T*8`($sp)
+	$POP	r25,`$FRAME-$SIZE_T*7`($sp)
+	$POP	r26,`$FRAME-$SIZE_T*6`($sp)
+	$POP	r27,`$FRAME-$SIZE_T*5`($sp)
+	$POP	r28,`$FRAME-$SIZE_T*4`($sp)
+	$POP	r29,`$FRAME-$SIZE_T*3`($sp)
+	$POP	r30,`$FRAME-$SIZE_T*2`($sp)
+	$POP	r31,`$FRAME-$SIZE_T*1`($sp)
+	mtlr	r0
+	addi	$sp,$sp,$FRAME
+	blr
+
+.align	4
+Lppc_AES_decrypt:
+	lwz	$acc00,240($key)
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	addi	$Tbl1,$Tbl0,3
+	addi	$Tbl2,$Tbl0,2
+	addi	$Tbl3,$Tbl0,1
+	addi	$acc00,$acc00,-1
+	addi	$key,$key,16
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	mtctr	$acc00
+.align	4
+Ldec_loop:
+	rlwinm	$acc00,$s0,`32-24+3`,21,28
+	rlwinm	$acc01,$s1,`32-24+3`,21,28
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	rlwinm	$acc02,$s2,`32-24+3`,21,28
+	rlwinm	$acc03,$s3,`32-24+3`,21,28
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	rlwinm	$acc04,$s3,`32-16+3`,21,28
+	rlwinm	$acc05,$s0,`32-16+3`,21,28
+	lwzx	$acc00,$Tbl0,$acc00
+	lwzx	$acc01,$Tbl0,$acc01
+	rlwinm	$acc06,$s1,`32-16+3`,21,28
+	rlwinm	$acc07,$s2,`32-16+3`,21,28
+	lwzx	$acc02,$Tbl0,$acc02
+	lwzx	$acc03,$Tbl0,$acc03
+	rlwinm	$acc08,$s2,`32-8+3`,21,28
+	rlwinm	$acc09,$s3,`32-8+3`,21,28
+	lwzx	$acc04,$Tbl1,$acc04
+	lwzx	$acc05,$Tbl1,$acc05
+	rlwinm	$acc10,$s0,`32-8+3`,21,28
+	rlwinm	$acc11,$s1,`32-8+3`,21,28
+	lwzx	$acc06,$Tbl1,$acc06
+	lwzx	$acc07,$Tbl1,$acc07
+	rlwinm	$acc12,$s1,`0+3`,21,28
+	rlwinm	$acc13,$s2,`0+3`,21,28
+	lwzx	$acc08,$Tbl2,$acc08
+	lwzx	$acc09,$Tbl2,$acc09
+	rlwinm	$acc14,$s3,`0+3`,21,28
+	rlwinm	$acc15,$s0,`0+3`,21,28
+	lwzx	$acc10,$Tbl2,$acc10
+	lwzx	$acc11,$Tbl2,$acc11
+	xor	$t0,$t0,$acc00
+	xor	$t1,$t1,$acc01
+	lwzx	$acc12,$Tbl3,$acc12
+	lwzx	$acc13,$Tbl3,$acc13
+	xor	$t2,$t2,$acc02
+	xor	$t3,$t3,$acc03
+	lwzx	$acc14,$Tbl3,$acc14
+	lwzx	$acc15,$Tbl3,$acc15
+	xor	$t0,$t0,$acc04
+	xor	$t1,$t1,$acc05
+	xor	$t2,$t2,$acc06
+	xor	$t3,$t3,$acc07
+	xor	$t0,$t0,$acc08
+	xor	$t1,$t1,$acc09
+	xor	$t2,$t2,$acc10
+	xor	$t3,$t3,$acc11
+	xor	$s0,$t0,$acc12
+	xor	$s1,$t1,$acc13
+	xor	$s2,$t2,$acc14
+	xor	$s3,$t3,$acc15
+	addi	$key,$key,16
+	bdnz-	Ldec_loop
+
+	addi	$Tbl2,$Tbl0,2048
+	nop
+	lwz	$acc08,`2048+0`($Tbl0)	! prefetch Td4
+	lwz	$acc09,`2048+32`($Tbl0)
+	lwz	$acc10,`2048+64`($Tbl0)
+	lwz	$acc11,`2048+96`($Tbl0)
+	lwz	$acc08,`2048+128`($Tbl0)
+	lwz	$acc09,`2048+160`($Tbl0)
+	lwz	$acc10,`2048+192`($Tbl0)
+	lwz	$acc11,`2048+224`($Tbl0)
+	rlwinm	$acc00,$s0,`32-24`,24,31
+	rlwinm	$acc01,$s1,`32-24`,24,31
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	rlwinm	$acc02,$s2,`32-24`,24,31
+	rlwinm	$acc03,$s3,`32-24`,24,31
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	rlwinm	$acc04,$s3,`32-16`,24,31
+	rlwinm	$acc05,$s0,`32-16`,24,31
+	lbzx	$acc00,$Tbl2,$acc00
+	lbzx	$acc01,$Tbl2,$acc01
+	rlwinm	$acc06,$s1,`32-16`,24,31
+	rlwinm	$acc07,$s2,`32-16`,24,31
+	lbzx	$acc02,$Tbl2,$acc02
+	lbzx	$acc03,$Tbl2,$acc03
+	rlwinm	$acc08,$s2,`32-8`,24,31
+	rlwinm	$acc09,$s3,`32-8`,24,31
+	lbzx	$acc04,$Tbl2,$acc04
+	lbzx	$acc05,$Tbl2,$acc05
+	rlwinm	$acc10,$s0,`32-8`,24,31
+	rlwinm	$acc11,$s1,`32-8`,24,31
+	lbzx	$acc06,$Tbl2,$acc06
+	lbzx	$acc07,$Tbl2,$acc07
+	rlwinm	$acc12,$s1,`0`,24,31
+	rlwinm	$acc13,$s2,`0`,24,31
+	lbzx	$acc08,$Tbl2,$acc08
+	lbzx	$acc09,$Tbl2,$acc09
+	rlwinm	$acc14,$s3,`0`,24,31
+	rlwinm	$acc15,$s0,`0`,24,31
+	lbzx	$acc10,$Tbl2,$acc10
+	lbzx	$acc11,$Tbl2,$acc11
+	rlwinm	$s0,$acc00,24,0,7
+	rlwinm	$s1,$acc01,24,0,7
+	lbzx	$acc12,$Tbl2,$acc12
+	lbzx	$acc13,$Tbl2,$acc13
+	rlwinm	$s2,$acc02,24,0,7
+	rlwinm	$s3,$acc03,24,0,7
+	lbzx	$acc14,$Tbl2,$acc14
+	lbzx	$acc15,$Tbl2,$acc15
+	rlwimi	$s0,$acc04,16,8,15
+	rlwimi	$s1,$acc05,16,8,15
+	rlwimi	$s2,$acc06,16,8,15
+	rlwimi	$s3,$acc07,16,8,15
+	rlwimi	$s0,$acc08,8,16,23
+	rlwimi	$s1,$acc09,8,16,23
+	rlwimi	$s2,$acc10,8,16,23
+	rlwimi	$s3,$acc11,8,16,23
+	or	$s0,$s0,$acc12
+	or	$s1,$s1,$acc13
+	or	$s2,$s2,$acc14
+	or	$s3,$s3,$acc15
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	blr
+
+.align	4
+Lppc_AES_decrypt_compact:
+	lwz	$acc00,240($key)
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	addi	$Tbl1,$Tbl0,2048
+	lis	$mask80,0x8080
+	lis	$mask1b,0x1b1b
+	addi	$key,$key,16
+	ori	$mask80,$mask80,0x8080
+	ori	$mask1b,$mask1b,0x1b1b
+___
+$code.=<<___ if ($SIZE_T==8);
+	insrdi	$mask80,$mask80,32,0
+	insrdi	$mask1b,$mask1b,32,0
+___
+$code.=<<___;
+	mtctr	$acc00
+.align	4
+Ldec_compact_loop:
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	rlwinm	$acc00,$s0,`32-24`,24,31
+	rlwinm	$acc01,$s1,`32-24`,24,31
+	rlwinm	$acc02,$s2,`32-24`,24,31
+	rlwinm	$acc03,$s3,`32-24`,24,31
+	lbzx	$acc00,$Tbl1,$acc00
+	lbzx	$acc01,$Tbl1,$acc01
+	rlwinm	$acc04,$s3,`32-16`,24,31
+	rlwinm	$acc05,$s0,`32-16`,24,31
+	lbzx	$acc02,$Tbl1,$acc02
+	lbzx	$acc03,$Tbl1,$acc03
+	rlwinm	$acc06,$s1,`32-16`,24,31
+	rlwinm	$acc07,$s2,`32-16`,24,31
+	lbzx	$acc04,$Tbl1,$acc04
+	lbzx	$acc05,$Tbl1,$acc05
+	rlwinm	$acc08,$s2,`32-8`,24,31
+	rlwinm	$acc09,$s3,`32-8`,24,31
+	lbzx	$acc06,$Tbl1,$acc06
+	lbzx	$acc07,$Tbl1,$acc07
+	rlwinm	$acc10,$s0,`32-8`,24,31
+	rlwinm	$acc11,$s1,`32-8`,24,31
+	lbzx	$acc08,$Tbl1,$acc08
+	lbzx	$acc09,$Tbl1,$acc09
+	rlwinm	$acc12,$s1,`0`,24,31
+	rlwinm	$acc13,$s2,`0`,24,31
+	lbzx	$acc10,$Tbl1,$acc10
+	lbzx	$acc11,$Tbl1,$acc11
+	rlwinm	$acc14,$s3,`0`,24,31
+	rlwinm	$acc15,$s0,`0`,24,31
+	lbzx	$acc12,$Tbl1,$acc12
+	lbzx	$acc13,$Tbl1,$acc13
+	rlwinm	$s0,$acc00,24,0,7
+	rlwinm	$s1,$acc01,24,0,7
+	lbzx	$acc14,$Tbl1,$acc14
+	lbzx	$acc15,$Tbl1,$acc15
+	rlwinm	$s2,$acc02,24,0,7
+	rlwinm	$s3,$acc03,24,0,7
+	rlwimi	$s0,$acc04,16,8,15
+	rlwimi	$s1,$acc05,16,8,15
+	rlwimi	$s2,$acc06,16,8,15
+	rlwimi	$s3,$acc07,16,8,15
+	rlwimi	$s0,$acc08,8,16,23
+	rlwimi	$s1,$acc09,8,16,23
+	rlwimi	$s2,$acc10,8,16,23
+	rlwimi	$s3,$acc11,8,16,23
+	lwz	$t0,0($key)
+	lwz	$t1,4($key)
+	or	$s0,$s0,$acc12
+	or	$s1,$s1,$acc13
+	lwz	$t2,8($key)
+	lwz	$t3,12($key)
+	or	$s2,$s2,$acc14
+	or	$s3,$s3,$acc15
+
+	addi	$key,$key,16
+	bdz	Ldec_compact_done
+___
+$code.=<<___ if ($SIZE_T==8);
+	# vectorized permutation improves decrypt performance by 10%
+	insrdi	$s0,$s1,32,0
+	insrdi	$s2,$s3,32,0
+
+	and	$acc00,$s0,$mask80	# r1=r0&0x80808080
+	and	$acc02,$s2,$mask80
+	srdi	$acc04,$acc00,7		# r1>>7
+	srdi	$acc06,$acc02,7
+	andc	$acc08,$s0,$mask80	# r0&0x7f7f7f7f
+	andc	$acc10,$s2,$mask80
+	sub	$acc00,$acc00,$acc04	# r1-(r1>>7)
+	sub	$acc02,$acc02,$acc06
+	add	$acc08,$acc08,$acc08	# (r0&0x7f7f7f7f)<<1
+	add	$acc10,$acc10,$acc10
+	and	$acc00,$acc00,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc02,$acc02,$mask1b
+	xor	$acc00,$acc00,$acc08	# r2
+	xor	$acc02,$acc02,$acc10
+
+	and	$acc04,$acc00,$mask80	# r1=r2&0x80808080
+	and	$acc06,$acc02,$mask80
+	srdi	$acc08,$acc04,7		# r1>>7
+	srdi	$acc10,$acc06,7
+	andc	$acc12,$acc00,$mask80	# r2&0x7f7f7f7f
+	andc	$acc14,$acc02,$mask80
+	sub	$acc04,$acc04,$acc08	# r1-(r1>>7)
+	sub	$acc06,$acc06,$acc10
+	add	$acc12,$acc12,$acc12	# (r2&0x7f7f7f7f)<<1
+	add	$acc14,$acc14,$acc14
+	and	$acc04,$acc04,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc06,$acc06,$mask1b
+	xor	$acc04,$acc04,$acc12	# r4
+	xor	$acc06,$acc06,$acc14
+
+	and	$acc08,$acc04,$mask80	# r1=r4&0x80808080
+	and	$acc10,$acc06,$mask80
+	srdi	$acc12,$acc08,7		# r1>>7
+	srdi	$acc14,$acc10,7
+	sub	$acc08,$acc08,$acc12	# r1-(r1>>7)
+	sub	$acc10,$acc10,$acc14
+	andc	$acc12,$acc04,$mask80	# r4&0x7f7f7f7f
+	andc	$acc14,$acc06,$mask80
+	add	$acc12,$acc12,$acc12	# (r4&0x7f7f7f7f)<<1
+	add	$acc14,$acc14,$acc14
+	and	$acc08,$acc08,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc10,$acc10,$mask1b
+	xor	$acc08,$acc08,$acc12	# r8
+	xor	$acc10,$acc10,$acc14
+
+	xor	$acc00,$acc00,$s0	# r2^r0
+	xor	$acc02,$acc02,$s2
+	xor	$acc04,$acc04,$s0	# r4^r0
+	xor	$acc06,$acc06,$s2
+
+	extrdi	$acc01,$acc00,32,0
+	extrdi	$acc03,$acc02,32,0
+	extrdi	$acc05,$acc04,32,0
+	extrdi	$acc07,$acc06,32,0
+	extrdi	$acc09,$acc08,32,0
+	extrdi	$acc11,$acc10,32,0
+___
+$code.=<<___ if ($SIZE_T==4);
+	and	$acc00,$s0,$mask80	# r1=r0&0x80808080
+	and	$acc01,$s1,$mask80
+	and	$acc02,$s2,$mask80
+	and	$acc03,$s3,$mask80
+	srwi	$acc04,$acc00,7		# r1>>7
+	srwi	$acc05,$acc01,7
+	srwi	$acc06,$acc02,7
+	srwi	$acc07,$acc03,7
+	andc	$acc08,$s0,$mask80	# r0&0x7f7f7f7f
+	andc	$acc09,$s1,$mask80
+	andc	$acc10,$s2,$mask80
+	andc	$acc11,$s3,$mask80
+	sub	$acc00,$acc00,$acc04	# r1-(r1>>7)
+	sub	$acc01,$acc01,$acc05
+	sub	$acc02,$acc02,$acc06
+	sub	$acc03,$acc03,$acc07
+	add	$acc08,$acc08,$acc08	# (r0&0x7f7f7f7f)<<1
+	add	$acc09,$acc09,$acc09
+	add	$acc10,$acc10,$acc10
+	add	$acc11,$acc11,$acc11
+	and	$acc00,$acc00,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc01,$acc01,$mask1b
+	and	$acc02,$acc02,$mask1b
+	and	$acc03,$acc03,$mask1b
+	xor	$acc00,$acc00,$acc08	# r2
+	xor	$acc01,$acc01,$acc09
+	xor	$acc02,$acc02,$acc10
+	xor	$acc03,$acc03,$acc11
+
+	and	$acc04,$acc00,$mask80	# r1=r2&0x80808080
+	and	$acc05,$acc01,$mask80
+	and	$acc06,$acc02,$mask80
+	and	$acc07,$acc03,$mask80
+	srwi	$acc08,$acc04,7		# r1>>7
+	srwi	$acc09,$acc05,7
+	srwi	$acc10,$acc06,7
+	srwi	$acc11,$acc07,7
+	andc	$acc12,$acc00,$mask80	# r2&0x7f7f7f7f
+	andc	$acc13,$acc01,$mask80
+	andc	$acc14,$acc02,$mask80
+	andc	$acc15,$acc03,$mask80
+	sub	$acc04,$acc04,$acc08	# r1-(r1>>7)
+	sub	$acc05,$acc05,$acc09
+	sub	$acc06,$acc06,$acc10
+	sub	$acc07,$acc07,$acc11
+	add	$acc12,$acc12,$acc12	# (r2&0x7f7f7f7f)<<1
+	add	$acc13,$acc13,$acc13
+	add	$acc14,$acc14,$acc14
+	add	$acc15,$acc15,$acc15
+	and	$acc04,$acc04,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc05,$acc05,$mask1b
+	and	$acc06,$acc06,$mask1b
+	and	$acc07,$acc07,$mask1b
+	xor	$acc04,$acc04,$acc12	# r4
+	xor	$acc05,$acc05,$acc13
+	xor	$acc06,$acc06,$acc14
+	xor	$acc07,$acc07,$acc15
+
+	and	$acc08,$acc04,$mask80	# r1=r4&0x80808080
+	and	$acc09,$acc05,$mask80
+	and	$acc10,$acc06,$mask80
+	and	$acc11,$acc07,$mask80
+	srwi	$acc12,$acc08,7		# r1>>7
+	srwi	$acc13,$acc09,7
+	srwi	$acc14,$acc10,7
+	srwi	$acc15,$acc11,7
+	sub	$acc08,$acc08,$acc12	# r1-(r1>>7)
+	sub	$acc09,$acc09,$acc13
+	sub	$acc10,$acc10,$acc14
+	sub	$acc11,$acc11,$acc15
+	andc	$acc12,$acc04,$mask80	# r4&0x7f7f7f7f
+	andc	$acc13,$acc05,$mask80
+	andc	$acc14,$acc06,$mask80
+	andc	$acc15,$acc07,$mask80
+	add	$acc12,$acc12,$acc12	# (r4&0x7f7f7f7f)<<1
+	add	$acc13,$acc13,$acc13
+	add	$acc14,$acc14,$acc14
+	add	$acc15,$acc15,$acc15
+	and	$acc08,$acc08,$mask1b	# (r1-(r1>>7))&0x1b1b1b1b
+	and	$acc09,$acc09,$mask1b
+	and	$acc10,$acc10,$mask1b
+	and	$acc11,$acc11,$mask1b
+	xor	$acc08,$acc08,$acc12	# r8
+	xor	$acc09,$acc09,$acc13
+	xor	$acc10,$acc10,$acc14
+	xor	$acc11,$acc11,$acc15
+
+	xor	$acc00,$acc00,$s0	# r2^r0
+	xor	$acc01,$acc01,$s1
+	xor	$acc02,$acc02,$s2
+	xor	$acc03,$acc03,$s3
+	xor	$acc04,$acc04,$s0	# r4^r0
+	xor	$acc05,$acc05,$s1
+	xor	$acc06,$acc06,$s2
+	xor	$acc07,$acc07,$s3
+___
+$code.=<<___;
+	rotrwi	$s0,$s0,8		# = ROTATE(r0,8)
+	rotrwi	$s1,$s1,8
+	rotrwi	$s2,$s2,8
+	rotrwi	$s3,$s3,8
+	xor	$s0,$s0,$acc00		# ^= r2^r0
+	xor	$s1,$s1,$acc01
+	xor	$s2,$s2,$acc02
+	xor	$s3,$s3,$acc03
+	xor	$acc00,$acc00,$acc08
+	xor	$acc01,$acc01,$acc09
+	xor	$acc02,$acc02,$acc10
+	xor	$acc03,$acc03,$acc11
+	xor	$s0,$s0,$acc04		# ^= r4^r0
+	xor	$s1,$s1,$acc05
+	xor	$s2,$s2,$acc06
+	xor	$s3,$s3,$acc07
+	rotrwi	$acc00,$acc00,24
+	rotrwi	$acc01,$acc01,24
+	rotrwi	$acc02,$acc02,24
+	rotrwi	$acc03,$acc03,24
+	xor	$acc04,$acc04,$acc08
+	xor	$acc05,$acc05,$acc09
+	xor	$acc06,$acc06,$acc10
+	xor	$acc07,$acc07,$acc11
+	xor	$s0,$s0,$acc08		# ^= r8 [^((r4^r0)^(r2^r0)=r4^r2)]
+	xor	$s1,$s1,$acc09
+	xor	$s2,$s2,$acc10
+	xor	$s3,$s3,$acc11
+	rotrwi	$acc04,$acc04,16
+	rotrwi	$acc05,$acc05,16
+	rotrwi	$acc06,$acc06,16
+	rotrwi	$acc07,$acc07,16
+	xor	$s0,$s0,$acc00		# ^= ROTATE(r8^r2^r0,24)
+	xor	$s1,$s1,$acc01
+	xor	$s2,$s2,$acc02
+	xor	$s3,$s3,$acc03
+	rotrwi	$acc08,$acc08,8
+	rotrwi	$acc09,$acc09,8
+	rotrwi	$acc10,$acc10,8
+	rotrwi	$acc11,$acc11,8
+	xor	$s0,$s0,$acc04		# ^= ROTATE(r8^r4^r0,16)
+	xor	$s1,$s1,$acc05
+	xor	$s2,$s2,$acc06
+	xor	$s3,$s3,$acc07
+	xor	$s0,$s0,$acc08		# ^= ROTATE(r8,8)	
+	xor	$s1,$s1,$acc09	
+	xor	$s2,$s2,$acc10	
+	xor	$s3,$s3,$acc11	
+
+	b	Ldec_compact_loop
+.align	4
+Ldec_compact_done:
+	xor	$s0,$s0,$t0
+	xor	$s1,$s1,$t1
+	xor	$s2,$s2,$t2
+	xor	$s3,$s3,$t3
+	blr
+.long	0
+.asciz	"AES for PPC, CRYPTOGAMS by <appro\@openssl.org>"
+.align	7
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/crypto/aes/asm/aes-s390x.pl b/crypto/aes/asm/aes-s390x.pl
new file mode 100644
index 0000000..4b27afd
--- /dev/null
+++ b/crypto/aes/asm/aes-s390x.pl
@@ -0,0 +1,1333 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# AES for s390x.
+
+# April 2007.
+#
+# Software performance improvement over gcc-generated code is ~70% and
+# in absolute terms is ~73 cycles per byte processed with 128-bit key.
+# You're likely to exclaim "why so slow?" Keep in mind that z-CPUs are
+# *strictly* in-order execution and issued instruction [in this case
+# load value from memory is critical] has to complete before execution
+# flow proceeds. S-boxes are compressed to 2KB[+256B].
+#
+# As for hardware acceleration support. It's basically a "teaser," as
+# it can and should be improved in several ways. Most notably support
+# for CBC is not utilized, nor multiple blocks are ever processed.
+# Then software key schedule can be postponed till hardware support
+# detection... Performance improvement over assembler is reportedly
+# ~2.5x, but can reach >8x [naturally on larger chunks] if proper
+# support is implemented.
+
+# May 2007.
+#
+# Implement AES_set_[en|de]crypt_key. Key schedule setup is avoided
+# for 128-bit keys, if hardware support is detected.
+
+# Januray 2009.
+#
+# Add support for hardware AES192/256 and reschedule instructions to
+# minimize/avoid Address Generation Interlock hazard and to favour
+# dual-issue z10 pipeline. This gave ~25% improvement on z10 and
+# almost 50% on z9. The gain is smaller on z10, because being dual-
+# issue z10 makes it improssible to eliminate the interlock condition:
+# critial path is not long enough. Yet it spends ~24 cycles per byte
+# processed with 128-bit key.
+#
+# Unlike previous version hardware support detection takes place only
+# at the moment of key schedule setup, which is denoted in key->rounds.
+# This is done, because deferred key setup can't be made MT-safe, not
+# for key lengthes longer than 128 bits.
+#
+# Add AES_cbc_encrypt, which gives incredible performance improvement,
+# it was measured to be ~6.6x. It's less than previously mentioned 8x,
+# because software implementation was optimized.
+
+$softonly=0;	# allow hardware support
+
+$t0="%r0";	$mask="%r0";
+$t1="%r1";
+$t2="%r2";	$inp="%r2";
+$t3="%r3";	$out="%r3";	$bits="%r3";
+$key="%r4";
+$i1="%r5";
+$i2="%r6";
+$i3="%r7";
+$s0="%r8";
+$s1="%r9";
+$s2="%r10";
+$s3="%r11";
+$tbl="%r12";
+$rounds="%r13";
+$ra="%r14";
+$sp="%r15";
+
+sub _data_word()
+{ my $i;
+    while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; }
+}
+
+$code=<<___;
+.text
+
+.type	AES_Te,\@object
+.align	256
+AES_Te:
+___
+&_data_word(
+	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
+	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
+	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
+	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
+	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
+	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
+	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
+	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
+	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
+	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
+	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
+	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
+	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
+	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
+	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
+	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
+	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
+	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
+	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
+	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
+	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
+	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
+	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
+	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
+	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
+	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
+	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
+	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
+	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
+	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
+	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
+	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
+	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
+	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
+	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
+	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
+	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
+	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
+	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
+	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
+	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
+	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
+	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
+	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
+	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
+	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
+	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
+	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
+	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
+	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
+	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
+	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
+	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
+	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
+	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
+	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
+	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
+	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
+	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
+	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
+	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
+	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
+	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
+	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
+$code.=<<___;
+# Te4[256]
+.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
+.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
+.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
+.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
+.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
+.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
+.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
+.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
+.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
+.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
+.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
+.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
+.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
+.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
+.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
+.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
+.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
+.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
+.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
+.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
+.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
+.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
+.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
+.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
+.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
+.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
+.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
+.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
+.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
+.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
+.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
+.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+# rcon[]
+.long	0x01000000, 0x02000000, 0x04000000, 0x08000000
+.long	0x10000000, 0x20000000, 0x40000000, 0x80000000
+.long	0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
+.align	256
+.size	AES_Te,.-AES_Te
+
+# void AES_encrypt(const unsigned char *inp, unsigned char *out,
+# 		 const AES_KEY *key) {
+.globl	AES_encrypt
+.type	AES_encrypt,\@function
+AES_encrypt:
+___
+$code.=<<___ if (!$softonly);
+	l	%r0,240($key)
+	lhi	%r1,16
+	clr	%r0,%r1
+	jl	.Lesoft
+
+	la	%r1,0($key)
+	#la	%r2,0($inp)
+	la	%r4,0($out)
+	lghi	%r3,16		# single block length
+	.long	0xb92e0042	# km %r4,%r2
+	brc	1,.-4		# can this happen?
+	br	%r14
+.align	64
+.Lesoft:
+___
+$code.=<<___;
+	stmg	%r3,$ra,24($sp)
+
+	llgf	$s0,0($inp)
+	llgf	$s1,4($inp)
+	llgf	$s2,8($inp)
+	llgf	$s3,12($inp)
+
+	larl	$tbl,AES_Te
+	bras	$ra,_s390x_AES_encrypt
+
+	lg	$out,24($sp)
+	st	$s0,0($out)
+	st	$s1,4($out)
+	st	$s2,8($out)
+	st	$s3,12($out)
+
+	lmg	%r6,$ra,48($sp)
+	br	$ra
+.size	AES_encrypt,.-AES_encrypt
+
+.type   _s390x_AES_encrypt,\@function
+.align	16
+_s390x_AES_encrypt:
+	stg	$ra,152($sp)
+	x	$s0,0($key)
+	x	$s1,4($key)
+	x	$s2,8($key)
+	x	$s3,12($key)
+	l	$rounds,240($key)
+	llill	$mask,`0xff<<3`
+	aghi	$rounds,-1
+	j	.Lenc_loop
+.align	16
+.Lenc_loop:
+	sllg	$t1,$s0,`0+3`
+	srlg	$t2,$s0,`8-3`
+	srlg	$t3,$s0,`16-3`
+	srl	$s0,`24-3`
+	nr	$s0,$mask
+	ngr	$t1,$mask
+	nr	$t2,$mask
+	nr	$t3,$mask
+
+	srlg	$i1,$s1,`16-3`	# i0
+	sllg	$i2,$s1,`0+3`
+	srlg	$i3,$s1,`8-3`
+	srl	$s1,`24-3`
+	nr	$i1,$mask
+	nr	$s1,$mask
+	ngr	$i2,$mask
+	nr	$i3,$mask
+
+	l	$s0,0($s0,$tbl)	# Te0[s0>>24]
+	l	$t1,1($t1,$tbl)	# Te3[s0>>0]
+	l	$t2,2($t2,$tbl) # Te2[s0>>8]
+	l	$t3,3($t3,$tbl)	# Te1[s0>>16]
+
+	x	$s0,3($i1,$tbl)	# Te1[s1>>16]
+	l	$s1,0($s1,$tbl)	# Te0[s1>>24]
+	x	$t2,1($i2,$tbl)	# Te3[s1>>0]
+	x	$t3,2($i3,$tbl)	# Te2[s1>>8]
+
+	srlg	$i1,$s2,`8-3`	# i0
+	srlg	$i2,$s2,`16-3`	# i1
+	nr	$i1,$mask
+	nr	$i2,$mask
+	sllg	$i3,$s2,`0+3`
+	srl	$s2,`24-3`
+	nr	$s2,$mask
+	ngr	$i3,$mask
+
+	xr	$s1,$t1
+	srlg	$ra,$s3,`8-3`	# i1
+	sllg	$t1,$s3,`0+3`	# i0
+	nr	$ra,$mask
+	la	$key,16($key)
+	ngr	$t1,$mask
+
+	x	$s0,2($i1,$tbl)	# Te2[s2>>8]
+	x	$s1,3($i2,$tbl)	# Te1[s2>>16]
+	l	$s2,0($s2,$tbl)	# Te0[s2>>24]
+	x	$t3,1($i3,$tbl)	# Te3[s2>>0]
+
+	srlg	$i3,$s3,`16-3`	# i2
+	xr	$s2,$t2
+	srl	$s3,`24-3`
+	nr	$i3,$mask
+	nr	$s3,$mask
+
+	x	$s0,0($key)
+	x	$s1,4($key)
+	x	$s2,8($key)
+	x	$t3,12($key)
+
+	x	$s0,1($t1,$tbl)	# Te3[s3>>0]
+	x	$s1,2($ra,$tbl)	# Te2[s3>>8]
+	x	$s2,3($i3,$tbl)	# Te1[s3>>16]
+	l	$s3,0($s3,$tbl)	# Te0[s3>>24]
+	xr	$s3,$t3
+
+	brct	$rounds,.Lenc_loop
+	.align	16
+
+	sllg	$t1,$s0,`0+3`
+	srlg	$t2,$s0,`8-3`
+	ngr	$t1,$mask
+	srlg	$t3,$s0,`16-3`
+	srl	$s0,`24-3`
+	nr	$s0,$mask
+	nr	$t2,$mask
+	nr	$t3,$mask
+
+	srlg	$i1,$s1,`16-3`	# i0
+	sllg	$i2,$s1,`0+3`
+	ngr	$i2,$mask
+	srlg	$i3,$s1,`8-3`
+	srl	$s1,`24-3`
+	nr	$i1,$mask
+	nr	$s1,$mask
+	nr	$i3,$mask
+
+	llgc	$s0,2($s0,$tbl)	# Te4[s0>>24]
+	llgc	$t1,2($t1,$tbl)	# Te4[s0>>0]
+	sll	$s0,24
+	llgc	$t2,2($t2,$tbl)	# Te4[s0>>8]
+	llgc	$t3,2($t3,$tbl)	# Te4[s0>>16]
+	sll	$t2,8
+	sll	$t3,16
+
+	llgc	$i1,2($i1,$tbl)	# Te4[s1>>16]
+	llgc	$s1,2($s1,$tbl)	# Te4[s1>>24]
+	llgc	$i2,2($i2,$tbl)	# Te4[s1>>0]
+	llgc	$i3,2($i3,$tbl)	# Te4[s1>>8]
+	sll	$i1,16
+	sll	$s1,24
+	sll	$i3,8
+	or	$s0,$i1
+	or	$s1,$t1
+	or	$t2,$i2
+	or	$t3,$i3
+	
+	srlg	$i1,$s2,`8-3`	# i0
+	srlg	$i2,$s2,`16-3`	# i1
+	nr	$i1,$mask
+	nr	$i2,$mask
+	sllg	$i3,$s2,`0+3`
+	srl	$s2,`24-3`
+	ngr	$i3,$mask
+	nr	$s2,$mask
+
+	sllg	$t1,$s3,`0+3`	# i0
+	srlg	$ra,$s3,`8-3`	# i1
+	ngr	$t1,$mask
+
+	llgc	$i1,2($i1,$tbl)	# Te4[s2>>8]
+	llgc	$i2,2($i2,$tbl)	# Te4[s2>>16]
+	sll	$i1,8
+	llgc	$s2,2($s2,$tbl)	# Te4[s2>>24]
+	llgc	$i3,2($i3,$tbl)	# Te4[s2>>0]
+	sll	$i2,16
+	nr	$ra,$mask
+	sll	$s2,24
+	or	$s0,$i1
+	or	$s1,$i2
+	or	$s2,$t2
+	or	$t3,$i3
+
+	srlg	$i3,$s3,`16-3`	# i2
+	srl	$s3,`24-3`
+	nr	$i3,$mask
+	nr	$s3,$mask
+
+	l	$t0,16($key)
+	l	$t2,20($key)
+
+	llgc	$i1,2($t1,$tbl)	# Te4[s3>>0]
+	llgc	$i2,2($ra,$tbl)	# Te4[s3>>8]
+	llgc	$i3,2($i3,$tbl)	# Te4[s3>>16]
+	llgc	$s3,2($s3,$tbl)	# Te4[s3>>24]
+	sll	$i2,8
+	sll	$i3,16
+	sll	$s3,24
+	or	$s0,$i1
+	or	$s1,$i2
+	or	$s2,$i3
+	or	$s3,$t3
+
+	lg	$ra,152($sp)
+	xr	$s0,$t0
+	xr	$s1,$t2
+	x	$s2,24($key)
+	x	$s3,28($key)
+
+	br	$ra	
+.size	_s390x_AES_encrypt,.-_s390x_AES_encrypt
+___
+
+$code.=<<___;
+.type	AES_Td,\@object
+.align	256
+AES_Td:
+___
+&_data_word(
+	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
+	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
+	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
+	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
+	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
+	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
+	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
+	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
+	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
+	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
+	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
+	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
+	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
+	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
+	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
+	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
+	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
+	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
+	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
+	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
+	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
+	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
+	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
+	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
+	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
+	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
+	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
+	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
+	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
+	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
+	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
+	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
+	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
+	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
+	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
+	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
+	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
+	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
+	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
+	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
+	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
+	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
+	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
+	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
+	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
+	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
+	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
+	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
+	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
+	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
+	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
+	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
+	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
+	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
+	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
+	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
+	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
+	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
+	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
+	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
+	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
+	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
+	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
+	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
+$code.=<<___;
+# Td4[256]
+.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
+.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
+.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
+.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
+.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
+.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
+.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
+.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
+.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
+.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
+.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
+.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
+.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
+.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
+.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
+.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
+.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+.size	AES_Td,.-AES_Td
+
+# void AES_decrypt(const unsigned char *inp, unsigned char *out,
+# 		 const AES_KEY *key) {
+.globl	AES_decrypt
+.type	AES_decrypt,\@function
+AES_decrypt:
+___
+$code.=<<___ if (!$softonly);
+	l	%r0,240($key)
+	lhi	%r1,16
+	clr	%r0,%r1
+	jl	.Ldsoft
+
+	la	%r1,0($key)
+	#la	%r2,0($inp)
+	la	%r4,0($out)
+	lghi	%r3,16		# single block length
+	.long	0xb92e0042	# km %r4,%r2
+	brc	1,.-4		# can this happen?
+	br	%r14
+.align	64
+.Ldsoft:
+___
+$code.=<<___;
+	stmg	%r3,$ra,24($sp)
+
+	llgf	$s0,0($inp)
+	llgf	$s1,4($inp)
+	llgf	$s2,8($inp)
+	llgf	$s3,12($inp)
+
+	larl	$tbl,AES_Td
+	bras	$ra,_s390x_AES_decrypt
+
+	lg	$out,24($sp)
+	st	$s0,0($out)
+	st	$s1,4($out)
+	st	$s2,8($out)
+	st	$s3,12($out)
+
+	lmg	%r6,$ra,48($sp)
+	br	$ra
+.size	AES_decrypt,.-AES_decrypt
+
+.type   _s390x_AES_decrypt,\@function
+.align	16
+_s390x_AES_decrypt:
+	stg	$ra,152($sp)
+	x	$s0,0($key)
+	x	$s1,4($key)
+	x	$s2,8($key)
+	x	$s3,12($key)
+	l	$rounds,240($key)
+	llill	$mask,`0xff<<3`
+	aghi	$rounds,-1
+	j	.Ldec_loop
+.align	16
+.Ldec_loop:
+	srlg	$t1,$s0,`16-3`
+	srlg	$t2,$s0,`8-3`
+	sllg	$t3,$s0,`0+3`
+	srl	$s0,`24-3`
+	nr	$s0,$mask
+	nr	$t1,$mask
+	nr	$t2,$mask
+	ngr	$t3,$mask
+
+	sllg	$i1,$s1,`0+3`	# i0
+	srlg	$i2,$s1,`16-3`
+	srlg	$i3,$s1,`8-3`
+	srl	$s1,`24-3`
+	ngr	$i1,$mask
+	nr	$s1,$mask
+	nr	$i2,$mask
+	nr	$i3,$mask
+
+	l	$s0,0($s0,$tbl)	# Td0[s0>>24]
+	l	$t1,3($t1,$tbl)	# Td1[s0>>16]
+	l	$t2,2($t2,$tbl)	# Td2[s0>>8]
+	l	$t3,1($t3,$tbl)	# Td3[s0>>0]
+
+	x	$s0,1($i1,$tbl)	# Td3[s1>>0]
+	l	$s1,0($s1,$tbl)	# Td0[s1>>24]
+	x	$t2,3($i2,$tbl)	# Td1[s1>>16]
+	x	$t3,2($i3,$tbl)	# Td2[s1>>8]
+
+	srlg	$i1,$s2,`8-3`	# i0
+	sllg	$i2,$s2,`0+3`	# i1
+	srlg	$i3,$s2,`16-3`
+	srl	$s2,`24-3`
+	nr	$i1,$mask
+	ngr	$i2,$mask
+	nr	$s2,$mask
+	nr	$i3,$mask
+
+	xr	$s1,$t1
+	srlg	$ra,$s3,`8-3`	# i1
+	srlg	$t1,$s3,`16-3`	# i0
+	nr	$ra,$mask
+	la	$key,16($key)
+	nr	$t1,$mask
+
+	x	$s0,2($i1,$tbl)	# Td2[s2>>8]
+	x	$s1,1($i2,$tbl)	# Td3[s2>>0]
+	l	$s2,0($s2,$tbl)	# Td0[s2>>24]
+	x	$t3,3($i3,$tbl)	# Td1[s2>>16]
+
+	sllg	$i3,$s3,`0+3`	# i2
+	srl	$s3,`24-3`
+	ngr	$i3,$mask
+	nr	$s3,$mask
+
+	xr	$s2,$t2
+	x	$s0,0($key)
+	x	$s1,4($key)
+	x	$s2,8($key)
+	x	$t3,12($key)
+
+	x	$s0,3($t1,$tbl)	# Td1[s3>>16]
+	x	$s1,2($ra,$tbl)	# Td2[s3>>8]
+	x	$s2,1($i3,$tbl)	# Td3[s3>>0]
+	l	$s3,0($s3,$tbl)	# Td0[s3>>24]
+	xr	$s3,$t3
+
+	brct	$rounds,.Ldec_loop
+	.align	16
+
+	l	$t1,`2048+0`($tbl)	# prefetch Td4
+	l	$t2,`2048+64`($tbl)
+	l	$t3,`2048+128`($tbl)
+	l	$i1,`2048+192`($tbl)
+	llill	$mask,0xff
+
+	srlg	$i3,$s0,24	# i0
+	srlg	$t1,$s0,16
+	srlg	$t2,$s0,8
+	nr	$s0,$mask	# i3
+	nr	$t1,$mask
+
+	srlg	$i1,$s1,24
+	nr	$t2,$mask
+	srlg	$i2,$s1,16
+	srlg	$ra,$s1,8
+	nr	$s1,$mask	# i0
+	nr	$i2,$mask
+	nr	$ra,$mask
+
+	llgc	$i3,2048($i3,$tbl)	# Td4[s0>>24]
+	llgc	$t1,2048($t1,$tbl)	# Td4[s0>>16]
+	llgc	$t2,2048($t2,$tbl)	# Td4[s0>>8]
+	sll	$t1,16
+	llgc	$t3,2048($s0,$tbl)	# Td4[s0>>0]
+	sllg	$s0,$i3,24
+	sll	$t2,8
+
+	llgc	$s1,2048($s1,$tbl)	# Td4[s1>>0]
+	llgc	$i1,2048($i1,$tbl)	# Td4[s1>>24]
+	llgc	$i2,2048($i2,$tbl)	# Td4[s1>>16]
+	sll	$i1,24
+	llgc	$i3,2048($ra,$tbl)	# Td4[s1>>8]
+	sll	$i2,16
+	sll	$i3,8
+	or	$s0,$s1
+	or	$t1,$i1
+	or	$t2,$i2
+	or	$t3,$i3
+
+	srlg	$i1,$s2,8	# i0
+	srlg	$i2,$s2,24
+	srlg	$i3,$s2,16
+	nr	$s2,$mask	# i1
+	nr	$i1,$mask
+	nr	$i3,$mask
+	llgc	$i1,2048($i1,$tbl)	# Td4[s2>>8]
+	llgc	$s1,2048($s2,$tbl)	# Td4[s2>>0]
+	llgc	$i2,2048($i2,$tbl)	# Td4[s2>>24]
+	llgc	$i3,2048($i3,$tbl)	# Td4[s2>>16]
+	sll	$i1,8
+	sll	$i2,24
+	or	$s0,$i1
+	sll	$i3,16
+	or	$t2,$i2
+	or	$t3,$i3
+
+	srlg	$i1,$s3,16	# i0
+	srlg	$i2,$s3,8	# i1
+	srlg	$i3,$s3,24
+	nr	$s3,$mask	# i2
+	nr	$i1,$mask
+	nr	$i2,$mask
+
+	lg	$ra,152($sp)
+	or	$s1,$t1
+	l	$t0,16($key)
+	l	$t1,20($key)
+
+	llgc	$i1,2048($i1,$tbl)	# Td4[s3>>16]
+	llgc	$i2,2048($i2,$tbl)	# Td4[s3>>8]
+	sll	$i1,16
+	llgc	$s2,2048($s3,$tbl)	# Td4[s3>>0]
+	llgc	$s3,2048($i3,$tbl)	# Td4[s3>>24]
+	sll	$i2,8
+	sll	$s3,24
+	or	$s0,$i1
+	or	$s1,$i2
+	or	$s2,$t2
+	or	$s3,$t3
+
+	xr	$s0,$t0
+	xr	$s1,$t1
+	x	$s2,24($key)
+	x	$s3,28($key)
+
+	br	$ra	
+.size	_s390x_AES_decrypt,.-_s390x_AES_decrypt
+___
+
+$code.=<<___;
+# void AES_set_encrypt_key(const unsigned char *in, int bits,
+# 		 AES_KEY *key) {
+.globl	AES_set_encrypt_key
+.type	AES_set_encrypt_key,\@function
+.align	16
+AES_set_encrypt_key:
+	lghi	$t0,0
+	clgr	$inp,$t0
+	je	.Lminus1
+	clgr	$key,$t0
+	je	.Lminus1
+
+	lghi	$t0,128
+	clr	$bits,$t0
+	je	.Lproceed
+	lghi	$t0,192
+	clr	$bits,$t0
+	je	.Lproceed
+	lghi	$t0,256
+	clr	$bits,$t0
+	je	.Lproceed
+	lghi	%r2,-2
+	br	%r14
+
+.align	16
+.Lproceed:
+___
+$code.=<<___ if (!$softonly);
+	# convert bits to km code, [128,192,256]->[18,19,20]
+	lhi	%r5,-128
+	lhi	%r0,18
+	ar	%r5,$bits
+	srl	%r5,6
+	ar	%r5,%r0
+
+	lghi	%r0,0		# query capability vector
+	la	%r1,16($sp)
+	.long	0xb92f0042	# kmc %r4,%r2
+
+	llihh	%r1,0x8000
+	srlg	%r1,%r1,0(%r5)
+	ng	%r1,16($sp)
+	jz	.Lekey_internal
+
+	lmg	%r0,%r1,0($inp)	# just copy 128 bits...
+	stmg	%r0,%r1,0($key)
+	lhi	%r0,192
+	cr	$bits,%r0
+	jl	1f
+	lg	%r1,16($inp)
+	stg	%r1,16($key)
+	je	1f
+	lg	%r1,24($inp)
+	stg	%r1,24($key)
+1:	st	$bits,236($key)	# save bits
+	st	%r5,240($key)	# save km code
+	lghi	%r2,0
+	br	%r14
+___
+$code.=<<___;
+.align	16
+.Lekey_internal:
+	stmg	%r6,%r13,48($sp)	# all non-volatile regs
+
+	larl	$tbl,AES_Te+2048
+
+	llgf	$s0,0($inp)
+	llgf	$s1,4($inp)
+	llgf	$s2,8($inp)
+	llgf	$s3,12($inp)
+	st	$s0,0($key)
+	st	$s1,4($key)
+	st	$s2,8($key)
+	st	$s3,12($key)
+	lghi	$t0,128
+	cr	$bits,$t0
+	jne	.Lnot128
+
+	llill	$mask,0xff
+	lghi	$t3,0			# i=0
+	lghi	$rounds,10
+	st	$rounds,240($key)
+
+	llgfr	$t2,$s3			# temp=rk[3]
+	srlg	$i1,$s3,8
+	srlg	$i2,$s3,16
+	srlg	$i3,$s3,24
+	nr	$t2,$mask
+	nr	$i1,$mask
+	nr	$i2,$mask
+
+.align	16
+.L128_loop:
+	la	$t2,0($t2,$tbl)
+	la	$i1,0($i1,$tbl)
+	la	$i2,0($i2,$tbl)
+	la	$i3,0($i3,$tbl)
+	icm	$t2,2,0($t2)		# Te4[rk[3]>>0]<<8
+	icm	$t2,4,0($i1)		# Te4[rk[3]>>8]<<16
+	icm	$t2,8,0($i2)		# Te4[rk[3]>>16]<<24
+	icm	$t2,1,0($i3)		# Te4[rk[3]>>24]
+	x	$t2,256($t3,$tbl)	# rcon[i]
+	xr	$s0,$t2			# rk[4]=rk[0]^...
+	xr	$s1,$s0			# rk[5]=rk[1]^rk[4]
+	xr	$s2,$s1			# rk[6]=rk[2]^rk[5]
+	xr	$s3,$s2			# rk[7]=rk[3]^rk[6]
+
+	llgfr	$t2,$s3			# temp=rk[3]
+	srlg	$i1,$s3,8
+	srlg	$i2,$s3,16
+	nr	$t2,$mask
+	nr	$i1,$mask
+	srlg	$i3,$s3,24
+	nr	$i2,$mask
+
+	st	$s0,16($key)
+	st	$s1,20($key)
+	st	$s2,24($key)
+	st	$s3,28($key)
+	la	$key,16($key)		# key+=4
+	la	$t3,4($t3)		# i++
+	brct	$rounds,.L128_loop
+	lghi	%r2,0
+	lmg	%r6,%r13,48($sp)
+	br	$ra
+
+.align	16
+.Lnot128:
+	llgf	$t0,16($inp)
+	llgf	$t1,20($inp)
+	st	$t0,16($key)
+	st	$t1,20($key)
+	lghi	$t0,192
+	cr	$bits,$t0
+	jne	.Lnot192
+
+	llill	$mask,0xff
+	lghi	$t3,0			# i=0
+	lghi	$rounds,12
+	st	$rounds,240($key)
+	lghi	$rounds,8
+
+	srlg	$i1,$t1,8
+	srlg	$i2,$t1,16
+	srlg	$i3,$t1,24
+	nr	$t1,$mask
+	nr	$i1,$mask
+	nr	$i2,$mask
+
+.align	16
+.L192_loop:
+	la	$t1,0($t1,$tbl)
+	la	$i1,0($i1,$tbl)
+	la	$i2,0($i2,$tbl)
+	la	$i3,0($i3,$tbl)
+	icm	$t1,2,0($t1)		# Te4[rk[5]>>0]<<8
+	icm	$t1,4,0($i1)		# Te4[rk[5]>>8]<<16
+	icm	$t1,8,0($i2)		# Te4[rk[5]>>16]<<24
+	icm	$t1,1,0($i3)		# Te4[rk[5]>>24]
+	x	$t1,256($t3,$tbl)	# rcon[i]
+	xr	$s0,$t1			# rk[6]=rk[0]^...
+	xr	$s1,$s0			# rk[7]=rk[1]^rk[6]
+	xr	$s2,$s1			# rk[8]=rk[2]^rk[7]
+	xr	$s3,$s2			# rk[9]=rk[3]^rk[8]
+
+	st	$s0,24($key)
+	st	$s1,28($key)
+	st	$s2,32($key)
+	st	$s3,36($key)
+	brct	$rounds,.L192_continue
+	lghi	%r2,0
+	lmg	%r6,%r13,48($sp)
+	br	$ra
+
+.align	16
+.L192_continue:
+	lgr	$t1,$s3
+	x	$t1,16($key)		# rk[10]=rk[4]^rk[9]
+	st	$t1,40($key)
+	x	$t1,20($key)		# rk[11]=rk[5]^rk[10]
+	st	$t1,44($key)
+
+	srlg	$i1,$t1,8
+	srlg	$i2,$t1,16
+	srlg	$i3,$t1,24
+	nr	$t1,$mask
+	nr	$i1,$mask
+	nr	$i2,$mask
+
+	la	$key,24($key)		# key+=6
+	la	$t3,4($t3)		# i++
+	j	.L192_loop
+
+.align	16
+.Lnot192:
+	llgf	$t0,24($inp)
+	llgf	$t1,28($inp)
+	st	$t0,24($key)
+	st	$t1,28($key)
+	llill	$mask,0xff
+	lghi	$t3,0			# i=0
+	lghi	$rounds,14
+	st	$rounds,240($key)
+	lghi	$rounds,7
+
+	srlg	$i1,$t1,8
+	srlg	$i2,$t1,16
+	srlg	$i3,$t1,24
+	nr	$t1,$mask
+	nr	$i1,$mask
+	nr	$i2,$mask
+
+.align	16
+.L256_loop:
+	la	$t1,0($t1,$tbl)
+	la	$i1,0($i1,$tbl)
+	la	$i2,0($i2,$tbl)
+	la	$i3,0($i3,$tbl)
+	icm	$t1,2,0($t1)		# Te4[rk[7]>>0]<<8
+	icm	$t1,4,0($i1)		# Te4[rk[7]>>8]<<16
+	icm	$t1,8,0($i2)		# Te4[rk[7]>>16]<<24
+	icm	$t1,1,0($i3)		# Te4[rk[7]>>24]
+	x	$t1,256($t3,$tbl)	# rcon[i]
+	xr	$s0,$t1			# rk[8]=rk[0]^...
+	xr	$s1,$s0			# rk[9]=rk[1]^rk[8]
+	xr	$s2,$s1			# rk[10]=rk[2]^rk[9]
+	xr	$s3,$s2			# rk[11]=rk[3]^rk[10]
+	st	$s0,32($key)
+	st	$s1,36($key)
+	st	$s2,40($key)
+	st	$s3,44($key)
+	brct	$rounds,.L256_continue
+	lghi	%r2,0
+	lmg	%r6,%r13,48($sp)
+	br	$ra
+
+.align	16
+.L256_continue:
+	lgr	$t1,$s3			# temp=rk[11]
+	srlg	$i1,$s3,8
+	srlg	$i2,$s3,16
+	srlg	$i3,$s3,24
+	nr	$t1,$mask
+	nr	$i1,$mask
+	nr	$i2,$mask
+	la	$t1,0($t1,$tbl)
+	la	$i1,0($i1,$tbl)
+	la	$i2,0($i2,$tbl)
+	la	$i3,0($i3,$tbl)
+	llgc	$t1,0($t1)		# Te4[rk[11]>>0]
+	icm	$t1,2,0($i1)		# Te4[rk[11]>>8]<<8
+	icm	$t1,4,0($i2)		# Te4[rk[11]>>16]<<16
+	icm	$t1,8,0($i3)		# Te4[rk[11]>>24]<<24
+	x	$t1,16($key)		# rk[12]=rk[4]^...
+	st	$t1,48($key)
+	x	$t1,20($key)		# rk[13]=rk[5]^rk[12]
+	st	$t1,52($key)
+	x	$t1,24($key)		# rk[14]=rk[6]^rk[13]
+	st	$t1,56($key)
+	x	$t1,28($key)		# rk[15]=rk[7]^rk[14]
+	st	$t1,60($key)
+
+	srlg	$i1,$t1,8
+	srlg	$i2,$t1,16
+	srlg	$i3,$t1,24
+	nr	$t1,$mask
+	nr	$i1,$mask
+	nr	$i2,$mask
+
+	la	$key,32($key)		# key+=8
+	la	$t3,4($t3)		# i++
+	j	.L256_loop
+
+.Lminus1:
+	lghi	%r2,-1
+	br	$ra
+.size	AES_set_encrypt_key,.-AES_set_encrypt_key
+
+# void AES_set_decrypt_key(const unsigned char *in, int bits,
+# 		 AES_KEY *key) {
+.globl	AES_set_decrypt_key
+.type	AES_set_decrypt_key,\@function
+.align	16
+AES_set_decrypt_key:
+	stg	$key,32($sp)		# I rely on AES_set_encrypt_key to
+	stg	$ra,112($sp)		# save non-volatile registers!
+	bras	$ra,AES_set_encrypt_key
+	lg	$key,32($sp)
+	lg	$ra,112($sp)
+	ltgr	%r2,%r2
+	bnzr	$ra
+___
+$code.=<<___ if (!$softonly);
+	l	$t0,240($key)
+	lhi	$t1,16
+	cr	$t0,$t1
+	jl	.Lgo
+	oill	$t0,0x80	# set "decrypt" bit
+	st	$t0,240($key)
+	br	$ra
+
+.align	16
+.Ldkey_internal:
+	stg	$key,32($sp)
+	stg	$ra,40($sp)
+	bras	$ra,.Lekey_internal
+	lg	$key,32($sp)
+	lg	$ra,40($sp)
+___
+$code.=<<___;
+
+.Lgo:	llgf	$rounds,240($key)
+	la	$i1,0($key)
+	sllg	$i2,$rounds,4
+	la	$i2,0($i2,$key)
+	srl	$rounds,1
+	lghi	$t1,-16
+
+.align	16
+.Linv:	lmg	$s0,$s1,0($i1)
+	lmg	$s2,$s3,0($i2)
+	stmg	$s0,$s1,0($i2)
+	stmg	$s2,$s3,0($i1)
+	la	$i1,16($i1)
+	la	$i2,0($t1,$i2)
+	brct	$rounds,.Linv
+___
+$mask80=$i1;
+$mask1b=$i2;
+$maskfe=$i3;
+$code.=<<___;
+	llgf	$rounds,240($key)
+	aghi	$rounds,-1
+	sll	$rounds,2	# (rounds-1)*4
+	llilh	$mask80,0x8080
+	llilh	$mask1b,0x1b1b
+	llilh	$maskfe,0xfefe
+	oill	$mask80,0x8080
+	oill	$mask1b,0x1b1b
+	oill	$maskfe,0xfefe
+
+.align	16
+.Lmix:	l	$s0,16($key)	# tp1
+	lr	$s1,$s0
+	ngr	$s1,$mask80
+	srlg	$t1,$s1,7
+	slr	$s1,$t1
+	nr	$s1,$mask1b
+	sllg	$t1,$s0,1
+	nr	$t1,$maskfe
+	xr	$s1,$t1		# tp2
+
+	lr	$s2,$s1
+	ngr	$s2,$mask80
+	srlg	$t1,$s2,7
+	slr	$s2,$t1
+	nr	$s2,$mask1b
+	sllg	$t1,$s1,1
+	nr	$t1,$maskfe
+	xr	$s2,$t1		# tp4
+
+	lr	$s3,$s2
+	ngr	$s3,$mask80
+	srlg	$t1,$s3,7
+	slr	$s3,$t1
+	nr	$s3,$mask1b
+	sllg	$t1,$s2,1
+	nr	$t1,$maskfe
+	xr	$s3,$t1		# tp8
+
+	xr	$s1,$s0		# tp2^tp1
+	xr	$s2,$s0		# tp4^tp1
+	rll	$s0,$s0,24	# = ROTATE(tp1,8)
+	xr	$s2,$s3		# ^=tp8
+	xr	$s0,$s1		# ^=tp2^tp1
+	xr	$s1,$s3		# tp2^tp1^tp8
+	xr	$s0,$s2		# ^=tp4^tp1^tp8
+	rll	$s1,$s1,8
+	rll	$s2,$s2,16
+	xr	$s0,$s1		# ^= ROTATE(tp8^tp2^tp1,24)
+	rll	$s3,$s3,24
+	xr	$s0,$s2    	# ^= ROTATE(tp8^tp4^tp1,16)
+	xr	$s0,$s3		# ^= ROTATE(tp8,8)
+
+	st	$s0,16($key)
+	la	$key,4($key)
+	brct	$rounds,.Lmix
+
+	lmg	%r6,%r13,48($sp)# as was saved by AES_set_encrypt_key!
+	lghi	%r2,0
+	br	$ra
+.size	AES_set_decrypt_key,.-AES_set_decrypt_key
+___
+
+#void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+#                     size_t length, const AES_KEY *key,
+#                     unsigned char *ivec, const int enc)
+{
+my $inp="%r2";
+my $out="%r4";	# length and out are swapped
+my $len="%r3";
+my $key="%r5";
+my $ivp="%r6";
+
+$code.=<<___;
+.globl	AES_cbc_encrypt
+.type	AES_cbc_encrypt,\@function
+.align	16
+AES_cbc_encrypt:
+	xgr	%r3,%r4		# flip %r3 and %r4, out and len
+	xgr	%r4,%r3
+	xgr	%r3,%r4
+___
+$code.=<<___ if (!$softonly);
+	lhi	%r0,16
+	cl	%r0,240($key)
+	jh	.Lcbc_software
+
+	lg	%r0,0($ivp)	# copy ivec
+	lg	%r1,8($ivp)
+	stmg	%r0,%r1,16($sp)
+	lmg	%r0,%r1,0($key)	# copy key, cover 256 bit
+	stmg	%r0,%r1,32($sp)
+	lmg	%r0,%r1,16($key)
+	stmg	%r0,%r1,48($sp)
+	l	%r0,240($key)	# load kmc code
+	lghi	$key,15		# res=len%16, len-=res;
+	ngr	$key,$len
+	slgr	$len,$key
+	la	%r1,16($sp)	# parameter block - ivec || key
+	jz	.Lkmc_truncated
+	.long	0xb92f0042	# kmc %r4,%r2
+	brc	1,.-4		# pay attention to "partial completion"
+	ltr	$key,$key
+	jnz	.Lkmc_truncated
+.Lkmc_done:
+	lmg	%r0,%r1,16($sp)	# copy ivec to caller
+	stg	%r0,0($ivp)
+	stg	%r1,8($ivp)
+	br	$ra
+.align	16
+.Lkmc_truncated:
+	ahi	$key,-1		# it's the way it's encoded in mvc
+	tmll	%r0,0x80
+	jnz	.Lkmc_truncated_dec
+	lghi	%r1,0
+	stg	%r1,128($sp)
+	stg	%r1,136($sp)
+	bras	%r1,1f
+	mvc	128(1,$sp),0($inp)
+1:	ex	$key,0(%r1)
+	la	%r1,16($sp)	# restore parameter block
+	la	$inp,128($sp)
+	lghi	$len,16
+	.long	0xb92f0042	# kmc %r4,%r2
+	j	.Lkmc_done
+.align	16
+.Lkmc_truncated_dec:
+	stg	$out,64($sp)
+	la	$out,128($sp)
+	lghi	$len,16
+	.long	0xb92f0042	# kmc %r4,%r2
+	lg	$out,64($sp)
+	bras	%r1,2f
+	mvc	0(1,$out),128($sp)
+2:	ex	$key,0(%r1)
+	j	.Lkmc_done
+.align	16
+.Lcbc_software:
+___
+$code.=<<___;
+	stmg	$key,$ra,40($sp)
+	lhi	%r0,0
+	cl	%r0,164($sp)
+	je	.Lcbc_decrypt
+
+	larl	$tbl,AES_Te
+
+	llgf	$s0,0($ivp)
+	llgf	$s1,4($ivp)
+	llgf	$s2,8($ivp)
+	llgf	$s3,12($ivp)
+
+	lghi	$t0,16
+	slgr	$len,$t0
+	brc	4,.Lcbc_enc_tail	# if borrow
+.Lcbc_enc_loop:
+	stmg	$inp,$out,16($sp)
+	x	$s0,0($inp)
+	x	$s1,4($inp)
+	x	$s2,8($inp)
+	x	$s3,12($inp)
+	lgr	%r4,$key
+
+	bras	$ra,_s390x_AES_encrypt
+
+	lmg	$inp,$key,16($sp)
+	st	$s0,0($out)
+	st	$s1,4($out)
+	st	$s2,8($out)
+	st	$s3,12($out)
+
+	la	$inp,16($inp)
+	la	$out,16($out)
+	lghi	$t0,16
+	ltgr	$len,$len
+	jz	.Lcbc_enc_done
+	slgr	$len,$t0
+	brc	4,.Lcbc_enc_tail	# if borrow
+	j	.Lcbc_enc_loop
+.align	16
+.Lcbc_enc_done:
+	lg	$ivp,48($sp)
+	st	$s0,0($ivp)
+	st	$s1,4($ivp)	
+	st	$s2,8($ivp)
+	st	$s3,12($ivp)
+
+	lmg	%r7,$ra,56($sp)
+	br	$ra
+
+.align	16
+.Lcbc_enc_tail:
+	aghi	$len,15
+	lghi	$t0,0
+	stg	$t0,128($sp)
+	stg	$t0,136($sp)
+	bras	$t1,3f
+	mvc	128(1,$sp),0($inp)
+3:	ex	$len,0($t1)
+	lghi	$len,0
+	la	$inp,128($sp)
+	j	.Lcbc_enc_loop
+
+.align	16
+.Lcbc_decrypt:
+	larl	$tbl,AES_Td
+
+	lg	$t0,0($ivp)
+	lg	$t1,8($ivp)
+	stmg	$t0,$t1,128($sp)
+
+.Lcbc_dec_loop:
+	stmg	$inp,$out,16($sp)
+	llgf	$s0,0($inp)
+	llgf	$s1,4($inp)
+	llgf	$s2,8($inp)
+	llgf	$s3,12($inp)
+	lgr	%r4,$key
+
+	bras	$ra,_s390x_AES_decrypt
+
+	lmg	$inp,$key,16($sp)
+	sllg	$s0,$s0,32
+	sllg	$s2,$s2,32
+	lr	$s0,$s1
+	lr	$s2,$s3
+
+	lg	$t0,0($inp)
+	lg	$t1,8($inp)
+	xg	$s0,128($sp)
+	xg	$s2,136($sp)
+	lghi	$s1,16
+	slgr	$len,$s1
+	brc	4,.Lcbc_dec_tail	# if borrow
+	brc	2,.Lcbc_dec_done	# if zero
+	stg	$s0,0($out)
+	stg	$s2,8($out)
+	stmg	$t0,$t1,128($sp)
+
+	la	$inp,16($inp)
+	la	$out,16($out)
+	j	.Lcbc_dec_loop
+
+.Lcbc_dec_done:
+	stg	$s0,0($out)
+	stg	$s2,8($out)
+.Lcbc_dec_exit:
+	lmg	$ivp,$ra,48($sp)
+	stmg	$t0,$t1,0($ivp)
+
+	br	$ra
+
+.align	16
+.Lcbc_dec_tail:
+	aghi	$len,15
+	stg	$s0,128($sp)
+	stg	$s2,136($sp)
+	bras	$s1,4f
+	mvc	0(1,$out),128($sp)
+4:	ex	$len,0($s1)
+	j	.Lcbc_dec_exit
+.size	AES_cbc_encrypt,.-AES_cbc_encrypt
+___
+}
+$code.=<<___;
+.string	"AES for s390x, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
diff --git a/crypto/aes/asm/aes-sparcv9.pl b/crypto/aes/asm/aes-sparcv9.pl
new file mode 100755
index 0000000..c57b3a2
--- /dev/null
+++ b/crypto/aes/asm/aes-sparcv9.pl
@@ -0,0 +1,1181 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. Rights for redistribution and usage in source and binary
+# forms are granted according to the OpenSSL license.
+# ====================================================================
+#
+# Version 1.1
+#
+# The major reason for undertaken effort was to mitigate the hazard of
+# cache-timing attack. This is [currently and initially!] addressed in
+# two ways. 1. S-boxes are compressed from 5KB to 2KB+256B size each.
+# 2. References to them are scheduled for L2 cache latency, meaning
+# that the tables don't have to reside in L1 cache. Once again, this
+# is an initial draft and one should expect more countermeasures to
+# be implemented...
+#
+# Version 1.1 prefetches T[ed]4 in order to mitigate attack on last
+# round.
+#
+# Even though performance was not the primary goal [on the contrary,
+# extra shifts "induced" by compressed S-box and longer loop epilogue
+# "induced" by scheduling for L2 have negative effect on performance],
+# the code turned out to run in ~23 cycles per processed byte en-/
+# decrypted with 128-bit key. This is pretty good result for code
+# with mentioned qualities and UltraSPARC core. Compared to Sun C
+# generated code my encrypt procedure runs just few percents faster,
+# while decrypt one - whole 50% faster [yes, Sun C failed to generate
+# optimal decrypt procedure]. Compared to GNU C generated code both
+# procedures are more than 60% faster:-)
+
+$bits=32;
+for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
+if ($bits==64)	{ $bias=2047; $frame=192; }
+else		{ $bias=0;    $frame=112; }
+$locals=16;
+
+$acc0="%l0";
+$acc1="%o0";
+$acc2="%o1";
+$acc3="%o2";
+
+$acc4="%l1";
+$acc5="%o3";
+$acc6="%o4";
+$acc7="%o5";
+
+$acc8="%l2";
+$acc9="%o7";
+$acc10="%g1";
+$acc11="%g2";
+
+$acc12="%l3";
+$acc13="%g3";
+$acc14="%g4";
+$acc15="%g5";
+
+$t0="%l4";
+$t1="%l5";
+$t2="%l6";
+$t3="%l7";
+
+$s0="%i0";
+$s1="%i1";
+$s2="%i2";
+$s3="%i3";
+$tbl="%i4";
+$key="%i5";
+$rounds="%i7";	# aliases with return address, which is off-loaded to stack
+
+sub _data_word()
+{ my $i;
+    while(defined($i=shift)) { $code.=sprintf"\t.long\t0x%08x,0x%08x\n",$i,$i; }
+}
+
+$code.=<<___ if ($bits==64);
+.register	%g2,#scratch
+.register	%g3,#scratch
+___
+$code.=<<___;
+.section	".text",#alloc,#execinstr
+
+.align	256
+AES_Te:
+___
+&_data_word(
+	0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
+	0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
+	0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
+	0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
+	0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
+	0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
+	0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
+	0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
+	0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
+	0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
+	0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
+	0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
+	0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
+	0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
+	0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
+	0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
+	0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
+	0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
+	0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
+	0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
+	0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
+	0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
+	0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
+	0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
+	0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
+	0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
+	0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
+	0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
+	0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
+	0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
+	0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
+	0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
+	0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
+	0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
+	0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
+	0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
+	0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
+	0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
+	0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
+	0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
+	0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
+	0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
+	0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
+	0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
+	0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
+	0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
+	0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
+	0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
+	0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
+	0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
+	0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
+	0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
+	0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
+	0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
+	0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
+	0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
+	0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
+	0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
+	0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
+	0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
+	0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
+	0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
+	0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
+	0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
+$code.=<<___;
+	.byte	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
+	.byte	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
+	.byte	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
+	.byte	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
+	.byte	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
+	.byte	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
+	.byte	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
+	.byte	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
+	.byte	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
+	.byte	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
+	.byte	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
+	.byte	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
+	.byte	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
+	.byte	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
+	.byte	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
+	.byte	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
+	.byte	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
+	.byte	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
+	.byte	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
+	.byte	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
+	.byte	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
+	.byte	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
+	.byte	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
+	.byte	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
+	.byte	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
+	.byte	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
+	.byte	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
+	.byte	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
+	.byte	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
+	.byte	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
+	.byte	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
+	.byte	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+.type	AES_Te,#object
+.size	AES_Te,(.-AES_Te)
+
+.align	64
+.skip	16
+_sparcv9_AES_encrypt:
+	save	%sp,-$frame-$locals,%sp
+	stx	%i7,[%sp+$bias+$frame+0]	! off-load return address
+	ld	[$key+240],$rounds
+	ld	[$key+0],$t0
+	ld	[$key+4],$t1			!
+	ld	[$key+8],$t2
+	srl	$rounds,1,$rounds
+	xor	$t0,$s0,$s0
+	ld	[$key+12],$t3
+	srl	$s0,21,$acc0
+	xor	$t1,$s1,$s1
+	ld	[$key+16],$t0
+	srl	$s1,13,$acc1			!
+	xor	$t2,$s2,$s2
+	ld	[$key+20],$t1
+	xor	$t3,$s3,$s3
+	ld	[$key+24],$t2
+	and	$acc0,2040,$acc0
+	ld	[$key+28],$t3
+	nop
+.Lenc_loop:
+	srl	$s2,5,$acc2			!
+	and	$acc1,2040,$acc1
+	ldx	[$tbl+$acc0],$acc0
+	sll	$s3,3,$acc3
+	and	$acc2,2040,$acc2
+	ldx	[$tbl+$acc1],$acc1
+	srl	$s1,21,$acc4
+	and	$acc3,2040,$acc3
+	ldx	[$tbl+$acc2],$acc2		!
+	srl	$s2,13,$acc5
+	and	$acc4,2040,$acc4
+	ldx	[$tbl+$acc3],$acc3
+	srl	$s3,5,$acc6
+	and	$acc5,2040,$acc5
+	ldx	[$tbl+$acc4],$acc4
+	fmovs	%f0,%f0
+	sll	$s0,3,$acc7			!
+	and	$acc6,2040,$acc6
+	ldx	[$tbl+$acc5],$acc5
+	srl	$s2,21,$acc8
+	and	$acc7,2040,$acc7
+	ldx	[$tbl+$acc6],$acc6
+	srl	$s3,13,$acc9
+	and	$acc8,2040,$acc8
+	ldx	[$tbl+$acc7],$acc7		!
+	srl	$s0,5,$acc10
+	and	$acc9,2040,$acc9
+	ldx	[$tbl+$acc8],$acc8
+	sll	$s1,3,$acc11
+	and	$acc10,2040,$acc10
+	ldx	[$tbl+$acc9],$acc9
+	fmovs	%f0,%f0
+	srl	$s3,21,$acc12			!
+	and	$acc11,2040,$acc11
+	ldx	[$tbl+$acc10],$acc10
+	srl	$s0,13,$acc13
+	and	$acc12,2040,$acc12
+	ldx	[$tbl+$acc11],$acc11
+	srl	$s1,5,$acc14
+	and	$acc13,2040,$acc13
+	ldx	[$tbl+$acc12],$acc12		!
+	sll	$s2,3,$acc15
+	and	$acc14,2040,$acc14
+	ldx	[$tbl+$acc13],$acc13
+	and	$acc15,2040,$acc15
+	add	$key,32,$key
+	ldx	[$tbl+$acc14],$acc14
+	fmovs	%f0,%f0
+	subcc	$rounds,1,$rounds		!
+	ldx	[$tbl+$acc15],$acc15
+	bz,a,pn	%icc,.Lenc_last
+	add	$tbl,2048,$rounds
+
+		srlx	$acc1,8,$acc1
+		xor	$acc0,$t0,$t0
+	ld	[$key+0],$s0
+	fmovs	%f0,%f0
+		srlx	$acc2,16,$acc2		!
+		xor	$acc1,$t0,$t0
+	ld	[$key+4],$s1
+		srlx	$acc3,24,$acc3
+		xor	$acc2,$t0,$t0
+	ld	[$key+8],$s2
+		srlx	$acc5,8,$acc5
+		xor	$acc3,$t0,$t0
+	ld	[$key+12],$s3			!
+		srlx	$acc6,16,$acc6
+		xor	$acc4,$t1,$t1
+	fmovs	%f0,%f0
+		srlx	$acc7,24,$acc7
+		xor	$acc5,$t1,$t1
+		srlx	$acc9,8,$acc9
+		xor	$acc6,$t1,$t1
+		srlx	$acc10,16,$acc10	!
+		xor	$acc7,$t1,$t1
+		srlx	$acc11,24,$acc11
+		xor	$acc8,$t2,$t2
+		srlx	$acc13,8,$acc13
+		xor	$acc9,$t2,$t2
+		srlx	$acc14,16,$acc14
+		xor	$acc10,$t2,$t2
+		srlx	$acc15,24,$acc15	!
+		xor	$acc11,$t2,$t2
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$t3,$t3
+	srl	$t0,21,$acc0
+		xor	$acc14,$t3,$t3
+	srl	$t1,13,$acc1
+		xor	$acc15,$t3,$t3
+
+	and	$acc0,2040,$acc0		!
+	srl	$t2,5,$acc2
+	and	$acc1,2040,$acc1
+	ldx	[$tbl+$acc0],$acc0
+	sll	$t3,3,$acc3
+	and	$acc2,2040,$acc2
+	ldx	[$tbl+$acc1],$acc1
+	fmovs	%f0,%f0
+	srl	$t1,21,$acc4			!
+	and	$acc3,2040,$acc3
+	ldx	[$tbl+$acc2],$acc2
+	srl	$t2,13,$acc5
+	and	$acc4,2040,$acc4
+	ldx	[$tbl+$acc3],$acc3
+	srl	$t3,5,$acc6
+	and	$acc5,2040,$acc5
+	ldx	[$tbl+$acc4],$acc4		!
+	sll	$t0,3,$acc7
+	and	$acc6,2040,$acc6
+	ldx	[$tbl+$acc5],$acc5
+	srl	$t2,21,$acc8
+	and	$acc7,2040,$acc7
+	ldx	[$tbl+$acc6],$acc6
+	fmovs	%f0,%f0
+	srl	$t3,13,$acc9			!
+	and	$acc8,2040,$acc8
+	ldx	[$tbl+$acc7],$acc7
+	srl	$t0,5,$acc10
+	and	$acc9,2040,$acc9
+	ldx	[$tbl+$acc8],$acc8
+	sll	$t1,3,$acc11
+	and	$acc10,2040,$acc10
+	ldx	[$tbl+$acc9],$acc9		!
+	srl	$t3,21,$acc12
+	and	$acc11,2040,$acc11
+	ldx	[$tbl+$acc10],$acc10
+	srl	$t0,13,$acc13
+	and	$acc12,2040,$acc12
+	ldx	[$tbl+$acc11],$acc11
+	fmovs	%f0,%f0
+	srl	$t1,5,$acc14			!
+	and	$acc13,2040,$acc13
+	ldx	[$tbl+$acc12],$acc12
+	sll	$t2,3,$acc15
+	and	$acc14,2040,$acc14
+	ldx	[$tbl+$acc13],$acc13
+		srlx	$acc1,8,$acc1
+	and	$acc15,2040,$acc15
+	ldx	[$tbl+$acc14],$acc14		!
+
+		srlx	$acc2,16,$acc2
+		xor	$acc0,$s0,$s0
+	ldx	[$tbl+$acc15],$acc15
+		srlx	$acc3,24,$acc3
+		xor	$acc1,$s0,$s0
+	ld	[$key+16],$t0
+	fmovs	%f0,%f0
+		srlx	$acc5,8,$acc5		!
+		xor	$acc2,$s0,$s0
+	ld	[$key+20],$t1
+		srlx	$acc6,16,$acc6
+		xor	$acc3,$s0,$s0
+	ld	[$key+24],$t2
+		srlx	$acc7,24,$acc7
+		xor	$acc4,$s1,$s1
+	ld	[$key+28],$t3			!
+		srlx	$acc9,8,$acc9
+		xor	$acc5,$s1,$s1
+	ldx	[$tbl+2048+0],%g0		! prefetch te4
+		srlx	$acc10,16,$acc10
+		xor	$acc6,$s1,$s1
+	ldx	[$tbl+2048+32],%g0		! prefetch te4
+		srlx	$acc11,24,$acc11
+		xor	$acc7,$s1,$s1
+	ldx	[$tbl+2048+64],%g0		! prefetch te4
+		srlx	$acc13,8,$acc13
+		xor	$acc8,$s2,$s2
+	ldx	[$tbl+2048+96],%g0		! prefetch te4
+		srlx	$acc14,16,$acc14	!
+		xor	$acc9,$s2,$s2
+	ldx	[$tbl+2048+128],%g0		! prefetch te4
+		srlx	$acc15,24,$acc15
+		xor	$acc10,$s2,$s2
+	ldx	[$tbl+2048+160],%g0		! prefetch te4
+	srl	$s0,21,$acc0
+		xor	$acc11,$s2,$s2
+	ldx	[$tbl+2048+192],%g0		! prefetch te4
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$s3,$s3
+	ldx	[$tbl+2048+224],%g0		! prefetch te4
+	srl	$s1,13,$acc1			!
+		xor	$acc14,$s3,$s3
+		xor	$acc15,$s3,$s3
+	ba	.Lenc_loop
+	and	$acc0,2040,$acc0
+
+.align	32
+.Lenc_last:
+		srlx	$acc1,8,$acc1		!
+		xor	$acc0,$t0,$t0
+	ld	[$key+0],$s0
+		srlx	$acc2,16,$acc2
+		xor	$acc1,$t0,$t0
+	ld	[$key+4],$s1
+		srlx	$acc3,24,$acc3
+		xor	$acc2,$t0,$t0
+	ld	[$key+8],$s2			!
+		srlx	$acc5,8,$acc5
+		xor	$acc3,$t0,$t0
+	ld	[$key+12],$s3
+		srlx	$acc6,16,$acc6
+		xor	$acc4,$t1,$t1
+		srlx	$acc7,24,$acc7
+		xor	$acc5,$t1,$t1
+		srlx	$acc9,8,$acc9		!
+		xor	$acc6,$t1,$t1
+		srlx	$acc10,16,$acc10
+		xor	$acc7,$t1,$t1
+		srlx	$acc11,24,$acc11
+		xor	$acc8,$t2,$t2
+		srlx	$acc13,8,$acc13
+		xor	$acc9,$t2,$t2
+		srlx	$acc14,16,$acc14	!
+		xor	$acc10,$t2,$t2
+		srlx	$acc15,24,$acc15
+		xor	$acc11,$t2,$t2
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$t3,$t3
+	srl	$t0,24,$acc0
+		xor	$acc14,$t3,$t3
+	srl	$t1,16,$acc1			!
+		xor	$acc15,$t3,$t3
+
+	srl	$t2,8,$acc2
+	and	$acc1,255,$acc1
+	ldub	[$rounds+$acc0],$acc0
+	srl	$t1,24,$acc4
+	and	$acc2,255,$acc2
+	ldub	[$rounds+$acc1],$acc1
+	srl	$t2,16,$acc5			!
+	and	$t3,255,$acc3
+	ldub	[$rounds+$acc2],$acc2
+	ldub	[$rounds+$acc3],$acc3
+	srl	$t3,8,$acc6
+	and	$acc5,255,$acc5
+	ldub	[$rounds+$acc4],$acc4
+	fmovs	%f0,%f0
+	srl	$t2,24,$acc8			!
+	and	$acc6,255,$acc6
+	ldub	[$rounds+$acc5],$acc5
+	srl	$t3,16,$acc9
+	and	$t0,255,$acc7
+	ldub	[$rounds+$acc6],$acc6
+	ldub	[$rounds+$acc7],$acc7
+	fmovs	%f0,%f0
+	srl	$t0,8,$acc10			!
+	and	$acc9,255,$acc9
+	ldub	[$rounds+$acc8],$acc8
+	srl	$t3,24,$acc12
+	and	$acc10,255,$acc10
+	ldub	[$rounds+$acc9],$acc9
+	srl	$t0,16,$acc13
+	and	$t1,255,$acc11
+	ldub	[$rounds+$acc10],$acc10		!
+	srl	$t1,8,$acc14
+	and	$acc13,255,$acc13
+	ldub	[$rounds+$acc11],$acc11
+	ldub	[$rounds+$acc12],$acc12
+	and	$acc14,255,$acc14
+	ldub	[$rounds+$acc13],$acc13
+	and	$t2,255,$acc15
+	ldub	[$rounds+$acc14],$acc14		!
+
+		sll	$acc0,24,$acc0
+		xor	$acc3,$s0,$s0
+	ldub	[$rounds+$acc15],$acc15
+		sll	$acc1,16,$acc1
+		xor	$acc0,$s0,$s0
+	ldx	[%sp+$bias+$frame+0],%i7	! restore return address
+	fmovs	%f0,%f0
+		sll	$acc2,8,$acc2		!
+		xor	$acc1,$s0,$s0
+		sll	$acc4,24,$acc4
+		xor	$acc2,$s0,$s0
+		sll	$acc5,16,$acc5
+		xor	$acc7,$s1,$s1
+		sll	$acc6,8,$acc6
+		xor	$acc4,$s1,$s1
+		sll	$acc8,24,$acc8		!
+		xor	$acc5,$s1,$s1
+		sll	$acc9,16,$acc9
+		xor	$acc11,$s2,$s2
+		sll	$acc10,8,$acc10
+		xor	$acc6,$s1,$s1
+		sll	$acc12,24,$acc12
+		xor	$acc8,$s2,$s2
+		sll	$acc13,16,$acc13	!
+		xor	$acc9,$s2,$s2
+		sll	$acc14,8,$acc14
+		xor	$acc10,$s2,$s2
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$s3,$s3
+		xor	$acc14,$s3,$s3
+		xor	$acc15,$s3,$s3
+
+	ret
+	restore
+.type	_sparcv9_AES_encrypt,#function
+.size	_sparcv9_AES_encrypt,(.-_sparcv9_AES_encrypt)
+
+.align	32
+.globl	AES_encrypt
+AES_encrypt:
+	or	%o0,%o1,%g1
+	andcc	%g1,3,%g0
+	bnz,pn	%xcc,.Lunaligned_enc
+	save	%sp,-$frame,%sp
+
+	ld	[%i0+0],%o0
+	ld	[%i0+4],%o1
+	ld	[%i0+8],%o2
+	ld	[%i0+12],%o3
+
+1:	call	.+8
+	add	%o7,AES_Te-1b,%o4
+	call	_sparcv9_AES_encrypt
+	mov	%i2,%o5
+
+	st	%o0,[%i1+0]
+	st	%o1,[%i1+4]
+	st	%o2,[%i1+8]
+	st	%o3,[%i1+12]
+
+	ret
+	restore
+
+.align	32
+.Lunaligned_enc:
+	ldub	[%i0+0],%l0
+	ldub	[%i0+1],%l1
+	ldub	[%i0+2],%l2
+
+	sll	%l0,24,%l0
+	ldub	[%i0+3],%l3
+	sll	%l1,16,%l1
+	ldub	[%i0+4],%l4
+	sll	%l2,8,%l2
+	or	%l1,%l0,%l0
+	ldub	[%i0+5],%l5
+	sll	%l4,24,%l4
+	or	%l3,%l2,%l2
+	ldub	[%i0+6],%l6
+	sll	%l5,16,%l5
+	or	%l0,%l2,%o0
+	ldub	[%i0+7],%l7
+
+	sll	%l6,8,%l6
+	or	%l5,%l4,%l4
+	ldub	[%i0+8],%l0
+	or	%l7,%l6,%l6
+	ldub	[%i0+9],%l1
+	or	%l4,%l6,%o1
+	ldub	[%i0+10],%l2
+
+	sll	%l0,24,%l0
+	ldub	[%i0+11],%l3
+	sll	%l1,16,%l1
+	ldub	[%i0+12],%l4
+	sll	%l2,8,%l2
+	or	%l1,%l0,%l0
+	ldub	[%i0+13],%l5
+	sll	%l4,24,%l4
+	or	%l3,%l2,%l2
+	ldub	[%i0+14],%l6
+	sll	%l5,16,%l5
+	or	%l0,%l2,%o2
+	ldub	[%i0+15],%l7
+
+	sll	%l6,8,%l6
+	or	%l5,%l4,%l4
+	or	%l7,%l6,%l6
+	or	%l4,%l6,%o3
+
+1:	call	.+8
+	add	%o7,AES_Te-1b,%o4
+	call	_sparcv9_AES_encrypt
+	mov	%i2,%o5
+
+	srl	%o0,24,%l0
+	srl	%o0,16,%l1
+	stb	%l0,[%i1+0]
+	srl	%o0,8,%l2
+	stb	%l1,[%i1+1]
+	stb	%l2,[%i1+2]
+	srl	%o1,24,%l4
+	stb	%o0,[%i1+3]
+
+	srl	%o1,16,%l5
+	stb	%l4,[%i1+4]
+	srl	%o1,8,%l6
+	stb	%l5,[%i1+5]
+	stb	%l6,[%i1+6]
+	srl	%o2,24,%l0
+	stb	%o1,[%i1+7]
+
+	srl	%o2,16,%l1
+	stb	%l0,[%i1+8]
+	srl	%o2,8,%l2
+	stb	%l1,[%i1+9]
+	stb	%l2,[%i1+10]
+	srl	%o3,24,%l4
+	stb	%o2,[%i1+11]
+
+	srl	%o3,16,%l5
+	stb	%l4,[%i1+12]
+	srl	%o3,8,%l6
+	stb	%l5,[%i1+13]
+	stb	%l6,[%i1+14]
+	stb	%o3,[%i1+15]
+
+	ret
+	restore
+.type	AES_encrypt,#function
+.size	AES_encrypt,(.-AES_encrypt)
+
+___
+
+$code.=<<___;
+.align	256
+AES_Td:
+___
+&_data_word(
+	0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
+	0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
+	0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
+	0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
+	0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
+	0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
+	0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
+	0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
+	0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
+	0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
+	0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
+	0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
+	0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
+	0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
+	0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
+	0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
+	0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
+	0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
+	0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
+	0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
+	0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
+	0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
+	0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
+	0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
+	0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
+	0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
+	0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
+	0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
+	0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
+	0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
+	0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
+	0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
+	0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
+	0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
+	0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
+	0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
+	0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
+	0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
+	0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
+	0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
+	0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
+	0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
+	0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
+	0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
+	0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
+	0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
+	0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
+	0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
+	0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
+	0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
+	0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
+	0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
+	0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
+	0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
+	0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
+	0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
+	0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
+	0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
+	0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
+	0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
+	0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
+	0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
+	0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
+	0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
+$code.=<<___;
+	.byte	0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
+	.byte	0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
+	.byte	0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
+	.byte	0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
+	.byte	0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
+	.byte	0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
+	.byte	0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
+	.byte	0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
+	.byte	0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
+	.byte	0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
+	.byte	0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
+	.byte	0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
+	.byte	0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
+	.byte	0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
+	.byte	0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
+	.byte	0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
+	.byte	0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
+	.byte	0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
+	.byte	0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
+	.byte	0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
+	.byte	0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
+	.byte	0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
+	.byte	0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
+	.byte	0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
+	.byte	0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
+	.byte	0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
+	.byte	0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
+	.byte	0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
+	.byte	0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
+	.byte	0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
+	.byte	0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
+	.byte	0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+.type	AES_Td,#object
+.size	AES_Td,(.-AES_Td)
+
+.align	64
+.skip	16
+_sparcv9_AES_decrypt:
+	save	%sp,-$frame-$locals,%sp
+	stx	%i7,[%sp+$bias+$frame+0]	! off-load return address
+	ld	[$key+240],$rounds
+	ld	[$key+0],$t0
+	ld	[$key+4],$t1			!
+	ld	[$key+8],$t2
+	ld	[$key+12],$t3
+	srl	$rounds,1,$rounds
+	xor	$t0,$s0,$s0
+	ld	[$key+16],$t0
+	xor	$t1,$s1,$s1
+	ld	[$key+20],$t1
+	srl	$s0,21,$acc0			!
+	xor	$t2,$s2,$s2
+	ld	[$key+24],$t2
+	xor	$t3,$s3,$s3
+	and	$acc0,2040,$acc0
+	ld	[$key+28],$t3
+	srl	$s3,13,$acc1
+	nop
+.Ldec_loop:
+	srl	$s2,5,$acc2			!
+	and	$acc1,2040,$acc1
+	ldx	[$tbl+$acc0],$acc0
+	sll	$s1,3,$acc3
+	and	$acc2,2040,$acc2
+	ldx	[$tbl+$acc1],$acc1
+	srl	$s1,21,$acc4
+	and	$acc3,2040,$acc3
+	ldx	[$tbl+$acc2],$acc2		!
+	srl	$s0,13,$acc5
+	and	$acc4,2040,$acc4
+	ldx	[$tbl+$acc3],$acc3
+	srl	$s3,5,$acc6
+	and	$acc5,2040,$acc5
+	ldx	[$tbl+$acc4],$acc4
+	fmovs	%f0,%f0
+	sll	$s2,3,$acc7			!
+	and	$acc6,2040,$acc6
+	ldx	[$tbl+$acc5],$acc5
+	srl	$s2,21,$acc8
+	and	$acc7,2040,$acc7
+	ldx	[$tbl+$acc6],$acc6
+	srl	$s1,13,$acc9
+	and	$acc8,2040,$acc8
+	ldx	[$tbl+$acc7],$acc7		!
+	srl	$s0,5,$acc10
+	and	$acc9,2040,$acc9
+	ldx	[$tbl+$acc8],$acc8
+	sll	$s3,3,$acc11
+	and	$acc10,2040,$acc10
+	ldx	[$tbl+$acc9],$acc9
+	fmovs	%f0,%f0
+	srl	$s3,21,$acc12			!
+	and	$acc11,2040,$acc11
+	ldx	[$tbl+$acc10],$acc10
+	srl	$s2,13,$acc13
+	and	$acc12,2040,$acc12
+	ldx	[$tbl+$acc11],$acc11
+	srl	$s1,5,$acc14
+	and	$acc13,2040,$acc13
+	ldx	[$tbl+$acc12],$acc12		!
+	sll	$s0,3,$acc15
+	and	$acc14,2040,$acc14
+	ldx	[$tbl+$acc13],$acc13
+	and	$acc15,2040,$acc15
+	add	$key,32,$key
+	ldx	[$tbl+$acc14],$acc14
+	fmovs	%f0,%f0
+	subcc	$rounds,1,$rounds		!
+	ldx	[$tbl+$acc15],$acc15
+	bz,a,pn	%icc,.Ldec_last
+	add	$tbl,2048,$rounds
+
+		srlx	$acc1,8,$acc1
+		xor	$acc0,$t0,$t0
+	ld	[$key+0],$s0
+	fmovs	%f0,%f0
+		srlx	$acc2,16,$acc2		!
+		xor	$acc1,$t0,$t0
+	ld	[$key+4],$s1
+		srlx	$acc3,24,$acc3
+		xor	$acc2,$t0,$t0
+	ld	[$key+8],$s2
+		srlx	$acc5,8,$acc5
+		xor	$acc3,$t0,$t0
+	ld	[$key+12],$s3			!
+		srlx	$acc6,16,$acc6
+		xor	$acc4,$t1,$t1
+	fmovs	%f0,%f0
+		srlx	$acc7,24,$acc7
+		xor	$acc5,$t1,$t1
+		srlx	$acc9,8,$acc9
+		xor	$acc6,$t1,$t1
+		srlx	$acc10,16,$acc10	!
+		xor	$acc7,$t1,$t1
+		srlx	$acc11,24,$acc11
+		xor	$acc8,$t2,$t2
+		srlx	$acc13,8,$acc13
+		xor	$acc9,$t2,$t2
+		srlx	$acc14,16,$acc14
+		xor	$acc10,$t2,$t2
+		srlx	$acc15,24,$acc15	!
+		xor	$acc11,$t2,$t2
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$t3,$t3
+	srl	$t0,21,$acc0
+		xor	$acc14,$t3,$t3
+		xor	$acc15,$t3,$t3
+	srl	$t3,13,$acc1
+
+	and	$acc0,2040,$acc0		!
+	srl	$t2,5,$acc2
+	and	$acc1,2040,$acc1
+	ldx	[$tbl+$acc0],$acc0
+	sll	$t1,3,$acc3
+	and	$acc2,2040,$acc2
+	ldx	[$tbl+$acc1],$acc1
+	fmovs	%f0,%f0
+	srl	$t1,21,$acc4			!
+	and	$acc3,2040,$acc3
+	ldx	[$tbl+$acc2],$acc2
+	srl	$t0,13,$acc5
+	and	$acc4,2040,$acc4
+	ldx	[$tbl+$acc3],$acc3
+	srl	$t3,5,$acc6
+	and	$acc5,2040,$acc5
+	ldx	[$tbl+$acc4],$acc4		!
+	sll	$t2,3,$acc7
+	and	$acc6,2040,$acc6
+	ldx	[$tbl+$acc5],$acc5
+	srl	$t2,21,$acc8
+	and	$acc7,2040,$acc7
+	ldx	[$tbl+$acc6],$acc6
+	fmovs	%f0,%f0
+	srl	$t1,13,$acc9			!
+	and	$acc8,2040,$acc8
+	ldx	[$tbl+$acc7],$acc7
+	srl	$t0,5,$acc10
+	and	$acc9,2040,$acc9
+	ldx	[$tbl+$acc8],$acc8
+	sll	$t3,3,$acc11
+	and	$acc10,2040,$acc10
+	ldx	[$tbl+$acc9],$acc9		!
+	srl	$t3,21,$acc12
+	and	$acc11,2040,$acc11
+	ldx	[$tbl+$acc10],$acc10
+	srl	$t2,13,$acc13
+	and	$acc12,2040,$acc12
+	ldx	[$tbl+$acc11],$acc11
+	fmovs	%f0,%f0
+	srl	$t1,5,$acc14			!
+	and	$acc13,2040,$acc13
+	ldx	[$tbl+$acc12],$acc12
+	sll	$t0,3,$acc15
+	and	$acc14,2040,$acc14
+	ldx	[$tbl+$acc13],$acc13
+		srlx	$acc1,8,$acc1
+	and	$acc15,2040,$acc15
+	ldx	[$tbl+$acc14],$acc14		!
+
+		srlx	$acc2,16,$acc2
+		xor	$acc0,$s0,$s0
+	ldx	[$tbl+$acc15],$acc15
+		srlx	$acc3,24,$acc3
+		xor	$acc1,$s0,$s0
+	ld	[$key+16],$t0
+	fmovs	%f0,%f0
+		srlx	$acc5,8,$acc5		!
+		xor	$acc2,$s0,$s0
+	ld	[$key+20],$t1
+		srlx	$acc6,16,$acc6
+		xor	$acc3,$s0,$s0
+	ld	[$key+24],$t2
+		srlx	$acc7,24,$acc7
+		xor	$acc4,$s1,$s1
+	ld	[$key+28],$t3			!
+		srlx	$acc9,8,$acc9
+		xor	$acc5,$s1,$s1
+	ldx	[$tbl+2048+0],%g0		! prefetch td4
+		srlx	$acc10,16,$acc10
+		xor	$acc6,$s1,$s1
+	ldx	[$tbl+2048+32],%g0		! prefetch td4
+		srlx	$acc11,24,$acc11
+		xor	$acc7,$s1,$s1
+	ldx	[$tbl+2048+64],%g0		! prefetch td4
+		srlx	$acc13,8,$acc13
+		xor	$acc8,$s2,$s2
+	ldx	[$tbl+2048+96],%g0		! prefetch td4
+		srlx	$acc14,16,$acc14	!
+		xor	$acc9,$s2,$s2
+	ldx	[$tbl+2048+128],%g0		! prefetch td4
+		srlx	$acc15,24,$acc15
+		xor	$acc10,$s2,$s2
+	ldx	[$tbl+2048+160],%g0		! prefetch td4
+	srl	$s0,21,$acc0
+		xor	$acc11,$s2,$s2
+	ldx	[$tbl+2048+192],%g0		! prefetch td4
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$s3,$s3
+	ldx	[$tbl+2048+224],%g0		! prefetch td4
+	and	$acc0,2040,$acc0		!
+		xor	$acc14,$s3,$s3
+		xor	$acc15,$s3,$s3
+	ba	.Ldec_loop
+	srl	$s3,13,$acc1
+
+.align	32
+.Ldec_last:
+		srlx	$acc1,8,$acc1		!
+		xor	$acc0,$t0,$t0
+	ld	[$key+0],$s0
+		srlx	$acc2,16,$acc2
+		xor	$acc1,$t0,$t0
+	ld	[$key+4],$s1
+		srlx	$acc3,24,$acc3
+		xor	$acc2,$t0,$t0
+	ld	[$key+8],$s2			!
+		srlx	$acc5,8,$acc5
+		xor	$acc3,$t0,$t0
+	ld	[$key+12],$s3
+		srlx	$acc6,16,$acc6
+		xor	$acc4,$t1,$t1
+		srlx	$acc7,24,$acc7
+		xor	$acc5,$t1,$t1
+		srlx	$acc9,8,$acc9		!
+		xor	$acc6,$t1,$t1
+		srlx	$acc10,16,$acc10
+		xor	$acc7,$t1,$t1
+		srlx	$acc11,24,$acc11
+		xor	$acc8,$t2,$t2
+		srlx	$acc13,8,$acc13
+		xor	$acc9,$t2,$t2
+		srlx	$acc14,16,$acc14	!
+		xor	$acc10,$t2,$t2
+		srlx	$acc15,24,$acc15
+		xor	$acc11,$t2,$t2
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$t3,$t3
+	srl	$t0,24,$acc0
+		xor	$acc14,$t3,$t3
+		xor	$acc15,$t3,$t3		!
+	srl	$t3,16,$acc1
+
+	srl	$t2,8,$acc2
+	and	$acc1,255,$acc1
+	ldub	[$rounds+$acc0],$acc0
+	srl	$t1,24,$acc4
+	and	$acc2,255,$acc2
+	ldub	[$rounds+$acc1],$acc1
+	srl	$t0,16,$acc5			!
+	and	$t1,255,$acc3
+	ldub	[$rounds+$acc2],$acc2
+	ldub	[$rounds+$acc3],$acc3
+	srl	$t3,8,$acc6
+	and	$acc5,255,$acc5
+	ldub	[$rounds+$acc4],$acc4
+	fmovs	%f0,%f0
+	srl	$t2,24,$acc8			!
+	and	$acc6,255,$acc6
+	ldub	[$rounds+$acc5],$acc5
+	srl	$t1,16,$acc9
+	and	$t2,255,$acc7
+	ldub	[$rounds+$acc6],$acc6
+	ldub	[$rounds+$acc7],$acc7
+	fmovs	%f0,%f0
+	srl	$t0,8,$acc10			!
+	and	$acc9,255,$acc9
+	ldub	[$rounds+$acc8],$acc8
+	srl	$t3,24,$acc12
+	and	$acc10,255,$acc10
+	ldub	[$rounds+$acc9],$acc9
+	srl	$t2,16,$acc13
+	and	$t3,255,$acc11
+	ldub	[$rounds+$acc10],$acc10		!
+	srl	$t1,8,$acc14
+	and	$acc13,255,$acc13
+	ldub	[$rounds+$acc11],$acc11
+	ldub	[$rounds+$acc12],$acc12
+	and	$acc14,255,$acc14
+	ldub	[$rounds+$acc13],$acc13
+	and	$t0,255,$acc15
+	ldub	[$rounds+$acc14],$acc14		!
+
+		sll	$acc0,24,$acc0
+		xor	$acc3,$s0,$s0
+	ldub	[$rounds+$acc15],$acc15
+		sll	$acc1,16,$acc1
+		xor	$acc0,$s0,$s0
+	ldx	[%sp+$bias+$frame+0],%i7	! restore return address
+	fmovs	%f0,%f0
+		sll	$acc2,8,$acc2		!
+		xor	$acc1,$s0,$s0
+		sll	$acc4,24,$acc4
+		xor	$acc2,$s0,$s0
+		sll	$acc5,16,$acc5
+		xor	$acc7,$s1,$s1
+		sll	$acc6,8,$acc6
+		xor	$acc4,$s1,$s1
+		sll	$acc8,24,$acc8		!
+		xor	$acc5,$s1,$s1
+		sll	$acc9,16,$acc9
+		xor	$acc11,$s2,$s2
+		sll	$acc10,8,$acc10
+		xor	$acc6,$s1,$s1
+		sll	$acc12,24,$acc12
+		xor	$acc8,$s2,$s2
+		sll	$acc13,16,$acc13	!
+		xor	$acc9,$s2,$s2
+		sll	$acc14,8,$acc14
+		xor	$acc10,$s2,$s2
+		xor	$acc12,$acc14,$acc14
+		xor	$acc13,$s3,$s3
+		xor	$acc14,$s3,$s3
+		xor	$acc15,$s3,$s3
+
+	ret
+	restore
+.type	_sparcv9_AES_decrypt,#function
+.size	_sparcv9_AES_decrypt,(.-_sparcv9_AES_decrypt)
+
+.align	32
+.globl	AES_decrypt
+AES_decrypt:
+	or	%o0,%o1,%g1
+	andcc	%g1,3,%g0
+	bnz,pn	%xcc,.Lunaligned_dec
+	save	%sp,-$frame,%sp
+
+	ld	[%i0+0],%o0
+	ld	[%i0+4],%o1
+	ld	[%i0+8],%o2
+	ld	[%i0+12],%o3
+
+1:	call	.+8
+	add	%o7,AES_Td-1b,%o4
+	call	_sparcv9_AES_decrypt
+	mov	%i2,%o5
+
+	st	%o0,[%i1+0]
+	st	%o1,[%i1+4]
+	st	%o2,[%i1+8]
+	st	%o3,[%i1+12]
+
+	ret
+	restore
+
+.align	32
+.Lunaligned_dec:
+	ldub	[%i0+0],%l0
+	ldub	[%i0+1],%l1
+	ldub	[%i0+2],%l2
+
+	sll	%l0,24,%l0
+	ldub	[%i0+3],%l3
+	sll	%l1,16,%l1
+	ldub	[%i0+4],%l4
+	sll	%l2,8,%l2
+	or	%l1,%l0,%l0
+	ldub	[%i0+5],%l5
+	sll	%l4,24,%l4
+	or	%l3,%l2,%l2
+	ldub	[%i0+6],%l6
+	sll	%l5,16,%l5
+	or	%l0,%l2,%o0
+	ldub	[%i0+7],%l7
+
+	sll	%l6,8,%l6
+	or	%l5,%l4,%l4
+	ldub	[%i0+8],%l0
+	or	%l7,%l6,%l6
+	ldub	[%i0+9],%l1
+	or	%l4,%l6,%o1
+	ldub	[%i0+10],%l2
+
+	sll	%l0,24,%l0
+	ldub	[%i0+11],%l3
+	sll	%l1,16,%l1
+	ldub	[%i0+12],%l4
+	sll	%l2,8,%l2
+	or	%l1,%l0,%l0
+	ldub	[%i0+13],%l5
+	sll	%l4,24,%l4
+	or	%l3,%l2,%l2
+	ldub	[%i0+14],%l6
+	sll	%l5,16,%l5
+	or	%l0,%l2,%o2
+	ldub	[%i0+15],%l7
+
+	sll	%l6,8,%l6
+	or	%l5,%l4,%l4
+	or	%l7,%l6,%l6
+	or	%l4,%l6,%o3
+
+1:	call	.+8
+	add	%o7,AES_Td-1b,%o4
+	call	_sparcv9_AES_decrypt
+	mov	%i2,%o5
+
+	srl	%o0,24,%l0
+	srl	%o0,16,%l1
+	stb	%l0,[%i1+0]
+	srl	%o0,8,%l2
+	stb	%l1,[%i1+1]
+	stb	%l2,[%i1+2]
+	srl	%o1,24,%l4
+	stb	%o0,[%i1+3]
+
+	srl	%o1,16,%l5
+	stb	%l4,[%i1+4]
+	srl	%o1,8,%l6
+	stb	%l5,[%i1+5]
+	stb	%l6,[%i1+6]
+	srl	%o2,24,%l0
+	stb	%o1,[%i1+7]
+
+	srl	%o2,16,%l1
+	stb	%l0,[%i1+8]
+	srl	%o2,8,%l2
+	stb	%l1,[%i1+9]
+	stb	%l2,[%i1+10]
+	srl	%o3,24,%l4
+	stb	%o2,[%i1+11]
+
+	srl	%o3,16,%l5
+	stb	%l4,[%i1+12]
+	srl	%o3,8,%l6
+	stb	%l5,[%i1+13]
+	stb	%l6,[%i1+14]
+	stb	%o3,[%i1+15]
+
+	ret
+	restore
+.type	AES_decrypt,#function
+.size	AES_decrypt,(.-AES_decrypt)
+___
+
+# fmovs instructions substituting for FP nops were originally added
+# to meet specific instruction alignment requirements to maximize ILP.
+# As UltraSPARC T1, a.k.a. Niagara, has shared FPU, FP nops can have
+# undesired effect, so just omit them and sacrifice some portion of
+# percent in performance...
+$code =~ s/fmovs.*$//gem;
+
+print $code;
diff --git a/crypto/aes/asm/aes-x86_64.pl b/crypto/aes/asm/aes-x86_64.pl
old mode 100644
new mode 100755
index 44e0bf8..f616f17
--- a/crypto/aes/asm/aes-x86_64.pl
+++ b/crypto/aes/asm/aes-x86_64.pl
@@ -1198,19 +1198,20 @@
 	ret
 .align	4
 .Lcbc_enc_tail:
-	cmp	$inp,$out
-	je	.Lcbc_enc_in_place
+	mov	%rax,%r11
+	mov	%rcx,%r12
 	mov	%r10,%rcx
 	mov	$inp,%rsi
 	mov	$out,%rdi
 	.long	0xF689A4F3		# rep movsb
-.Lcbc_enc_in_place:
 	mov	\$16,%rcx		# zero tail
 	sub	%r10,%rcx
 	xor	%rax,%rax
 	.long	0xF689AAF3		# rep stosb
 	mov	$out,$inp		# this is not a mistake!
 	movq	\$16,$_len		# len=16
+	mov	%r11,%rax
+	mov	%r12,%rcx
 	jmp	.Lcbc_enc_loop		# one more spin...
 #----------------------------- DECRYPT -----------------------------#
 .align	16
diff --git a/crypto/asn1/Makefile b/crypto/asn1/Makefile
index 6306689..94a6885 100644
--- a/crypto/asn1/Makefile
+++ b/crypto/asn1/Makefile
@@ -63,7 +63,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -142,9 +142,9 @@
 a_digest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 a_digest.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 a_digest.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-a_digest.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-a_digest.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-a_digest.o: ../../include/openssl/opensslconf.h
+a_digest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+a_digest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+a_digest.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 a_digest.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 a_digest.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 a_digest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -250,27 +250,27 @@
 a_sign.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 a_sign.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 a_sign.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-a_sign.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-a_sign.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-a_sign.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-a_sign.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-a_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-a_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-a_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-a_sign.o: ../cryptlib.h a_sign.c
+a_sign.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+a_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+a_sign.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+a_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+a_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+a_sign.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+a_sign.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+a_sign.o: ../../include/openssl/x509_vfy.h ../cryptlib.h a_sign.c
 a_strex.o: ../../e_os.h ../../include/openssl/asn1.h
 a_strex.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 a_strex.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 a_strex.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 a_strex.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-a_strex.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-a_strex.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-a_strex.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-a_strex.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-a_strex.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-a_strex.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-a_strex.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-a_strex.o: ../cryptlib.h a_strex.c charmap.h
+a_strex.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+a_strex.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+a_strex.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+a_strex.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+a_strex.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+a_strex.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+a_strex.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+a_strex.o: ../../include/openssl/x509_vfy.h ../cryptlib.h a_strex.c charmap.h
 a_strnid.o: ../../e_os.h ../../include/openssl/asn1.h
 a_strnid.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 a_strnid.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
@@ -318,8 +318,9 @@
 a_verify.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 a_verify.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 a_verify.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-a_verify.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-a_verify.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+a_verify.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+a_verify.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+a_verify.o: ../../include/openssl/opensslconf.h
 a_verify.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 a_verify.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 a_verify.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -338,8 +339,9 @@
 asn1_gen.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 asn1_gen.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 asn1_gen.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-asn1_gen.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-asn1_gen.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+asn1_gen.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+asn1_gen.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+asn1_gen.o: ../../include/openssl/opensslconf.h
 asn1_gen.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 asn1_gen.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 asn1_gen.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -369,8 +371,9 @@
 asn_mime.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 asn_mime.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 asn_mime.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-asn_mime.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-asn_mime.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+asn_mime.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+asn_mime.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+asn_mime.o: ../../include/openssl/opensslconf.h
 asn_mime.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 asn_mime.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
 asn_mime.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
@@ -383,9 +386,9 @@
 asn_moid.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
 asn_moid.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 asn_moid.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-asn_moid.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-asn_moid.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-asn_moid.o: ../../include/openssl/opensslconf.h
+asn_moid.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+asn_moid.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+asn_moid.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 asn_moid.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 asn_moid.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 asn_moid.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -404,23 +407,23 @@
 d2i_pr.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
 d2i_pr.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 d2i_pr.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-d2i_pr.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-d2i_pr.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-d2i_pr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-d2i_pr.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-d2i_pr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-d2i_pr.o: ../cryptlib.h d2i_pr.c
+d2i_pr.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+d2i_pr.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+d2i_pr.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+d2i_pr.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
+d2i_pr.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+d2i_pr.o: ../../include/openssl/symhacks.h ../cryptlib.h d2i_pr.c
 d2i_pu.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 d2i_pu.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
 d2i_pu.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
 d2i_pu.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 d2i_pu.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-d2i_pu.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-d2i_pu.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-d2i_pu.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-d2i_pu.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-d2i_pu.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-d2i_pu.o: ../cryptlib.h d2i_pu.c
+d2i_pu.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+d2i_pu.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+d2i_pu.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+d2i_pu.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
+d2i_pu.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+d2i_pu.o: ../../include/openssl/symhacks.h ../cryptlib.h d2i_pu.c
 evp_asn1.o: ../../e_os.h ../../include/openssl/asn1.h
 evp_asn1.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
 evp_asn1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
@@ -456,71 +459,73 @@
 i2d_pr.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
 i2d_pr.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 i2d_pr.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-i2d_pr.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-i2d_pr.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-i2d_pr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-i2d_pr.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-i2d_pr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-i2d_pr.o: ../cryptlib.h i2d_pr.c
+i2d_pr.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+i2d_pr.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+i2d_pr.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+i2d_pr.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
+i2d_pr.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+i2d_pr.o: ../../include/openssl/symhacks.h ../cryptlib.h i2d_pr.c
 i2d_pu.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 i2d_pu.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
 i2d_pu.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
 i2d_pu.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 i2d_pu.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-i2d_pu.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-i2d_pu.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-i2d_pu.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-i2d_pu.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-i2d_pu.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-i2d_pu.o: ../cryptlib.h i2d_pu.c
+i2d_pu.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+i2d_pu.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+i2d_pu.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+i2d_pu.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
+i2d_pu.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+i2d_pu.o: ../../include/openssl/symhacks.h ../cryptlib.h i2d_pu.c
 n_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
 n_pkey.o: ../../include/openssl/asn1_mac.h ../../include/openssl/asn1t.h
 n_pkey.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 n_pkey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 n_pkey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 n_pkey.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-n_pkey.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-n_pkey.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-n_pkey.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-n_pkey.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-n_pkey.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-n_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-n_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-n_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h n_pkey.c
+n_pkey.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+n_pkey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+n_pkey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+n_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+n_pkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+n_pkey.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+n_pkey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+n_pkey.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+n_pkey.o: ../cryptlib.h n_pkey.c
 nsseq.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
 nsseq.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 nsseq.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 nsseq.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 nsseq.o: ../../include/openssl/ecdsa.h ../../include/openssl/evp.h
-nsseq.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-nsseq.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-nsseq.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-nsseq.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-nsseq.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-nsseq.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-nsseq.o: ../../include/openssl/x509_vfy.h nsseq.c
+nsseq.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+nsseq.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+nsseq.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+nsseq.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+nsseq.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+nsseq.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+nsseq.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h nsseq.c
 p5_pbe.o: ../../e_os.h ../../include/openssl/asn1.h
 p5_pbe.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 p5_pbe.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 p5_pbe.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 p5_pbe.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 p5_pbe.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-p5_pbe.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-p5_pbe.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-p5_pbe.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-p5_pbe.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
-p5_pbe.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-p5_pbe.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-p5_pbe.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-p5_pbe.o: ../cryptlib.h p5_pbe.c
+p5_pbe.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+p5_pbe.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p5_pbe.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+p5_pbe.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+p5_pbe.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+p5_pbe.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+p5_pbe.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+p5_pbe.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p5_pbe.c
 p5_pbev2.o: ../../e_os.h ../../include/openssl/asn1.h
 p5_pbev2.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 p5_pbev2.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 p5_pbev2.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 p5_pbev2.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 p5_pbev2.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-p5_pbev2.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-p5_pbev2.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p5_pbev2.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+p5_pbev2.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p5_pbev2.o: ../../include/openssl/opensslconf.h
 p5_pbev2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 p5_pbev2.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
 p5_pbev2.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
@@ -533,41 +538,42 @@
 p8_pkey.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 p8_pkey.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 p8_pkey.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-p8_pkey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-p8_pkey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-p8_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-p8_pkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-p8_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-p8_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-p8_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p8_pkey.c
+p8_pkey.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+p8_pkey.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p8_pkey.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+p8_pkey.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+p8_pkey.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p8_pkey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p8_pkey.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p8_pkey.o: ../cryptlib.h p8_pkey.c
 t_bitst.o: ../../e_os.h ../../include/openssl/asn1.h
 t_bitst.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 t_bitst.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
 t_bitst.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 t_bitst.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 t_bitst.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-t_bitst.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-t_bitst.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-t_bitst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-t_bitst.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-t_bitst.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-t_bitst.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-t_bitst.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-t_bitst.o: ../cryptlib.h t_bitst.c
+t_bitst.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+t_bitst.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+t_bitst.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+t_bitst.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+t_bitst.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+t_bitst.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+t_bitst.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+t_bitst.o: ../../include/openssl/x509v3.h ../cryptlib.h t_bitst.c
 t_crl.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 t_crl.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
 t_crl.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
 t_crl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 t_crl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 t_crl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-t_crl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-t_crl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-t_crl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-t_crl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-t_crl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-t_crl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-t_crl.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-t_crl.o: ../cryptlib.h t_crl.c
+t_crl.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+t_crl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+t_crl.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+t_crl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+t_crl.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+t_crl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+t_crl.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+t_crl.o: ../../include/openssl/x509v3.h ../cryptlib.h t_crl.c
 t_pkey.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 t_pkey.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
 t_pkey.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
@@ -585,57 +591,57 @@
 t_req.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
 t_req.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 t_req.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-t_req.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-t_req.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-t_req.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-t_req.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-t_req.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-t_req.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-t_req.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-t_req.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-t_req.o: ../cryptlib.h t_req.c
+t_req.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+t_req.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+t_req.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+t_req.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+t_req.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+t_req.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+t_req.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+t_req.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+t_req.o: ../../include/openssl/x509v3.h ../cryptlib.h t_req.c
 t_spki.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 t_spki.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
 t_spki.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
 t_spki.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 t_spki.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 t_spki.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-t_spki.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-t_spki.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-t_spki.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-t_spki.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
-t_spki.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-t_spki.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-t_spki.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-t_spki.o: ../cryptlib.h t_spki.c
+t_spki.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+t_spki.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+t_spki.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+t_spki.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+t_spki.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+t_spki.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+t_spki.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+t_spki.o: ../../include/openssl/x509_vfy.h ../cryptlib.h t_spki.c
 t_x509.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 t_x509.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
 t_x509.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
 t_x509.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
 t_x509.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 t_x509.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-t_x509.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-t_x509.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-t_x509.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-t_x509.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-t_x509.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-t_x509.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-t_x509.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-t_x509.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-t_x509.o: ../cryptlib.h t_x509.c
+t_x509.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+t_x509.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+t_x509.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+t_x509.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+t_x509.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+t_x509.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+t_x509.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+t_x509.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+t_x509.o: ../../include/openssl/x509v3.h ../cryptlib.h t_x509.c
 t_x509a.o: ../../e_os.h ../../include/openssl/asn1.h
 t_x509a.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 t_x509a.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 t_x509a.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 t_x509a.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-t_x509a.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-t_x509a.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-t_x509a.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-t_x509a.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-t_x509a.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-t_x509a.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-t_x509a.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-t_x509a.o: ../cryptlib.h t_x509a.c
+t_x509a.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+t_x509a.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+t_x509a.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+t_x509a.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+t_x509a.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+t_x509a.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+t_x509a.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+t_x509a.o: ../../include/openssl/x509_vfy.h ../cryptlib.h t_x509a.c
 tasn_dec.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
 tasn_dec.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 tasn_dec.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
@@ -688,21 +694,23 @@
 x_algor.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 x_algor.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 x_algor.o: ../../include/openssl/ecdsa.h ../../include/openssl/evp.h
-x_algor.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x_algor.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-x_algor.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-x_algor.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-x_algor.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-x_algor.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x_algor.o: ../../include/openssl/x509_vfy.h x_algor.c
+x_algor.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x_algor.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x_algor.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+x_algor.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+x_algor.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+x_algor.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+x_algor.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x_algor.o: x_algor.c
 x_attrib.o: ../../e_os.h ../../include/openssl/asn1.h
 x_attrib.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 x_attrib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 x_attrib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x_attrib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x_attrib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x_attrib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x_attrib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x_attrib.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x_attrib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x_attrib.o: ../../include/openssl/opensslconf.h
 x_attrib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x_attrib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x_attrib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -723,37 +731,40 @@
 x_crl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x_crl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x_crl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x_crl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x_crl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-x_crl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-x_crl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-x_crl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-x_crl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x_crl.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_crl.c
+x_crl.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x_crl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x_crl.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+x_crl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+x_crl.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+x_crl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+x_crl.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x_crl.o: ../cryptlib.h x_crl.c
 x_exten.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
 x_exten.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 x_exten.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 x_exten.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 x_exten.o: ../../include/openssl/ecdsa.h ../../include/openssl/evp.h
-x_exten.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x_exten.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-x_exten.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-x_exten.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-x_exten.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-x_exten.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x_exten.o: ../../include/openssl/x509_vfy.h x_exten.c
+x_exten.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x_exten.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x_exten.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+x_exten.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+x_exten.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+x_exten.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+x_exten.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x_exten.o: x_exten.c
 x_info.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 x_info.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 x_info.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x_info.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x_info.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x_info.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x_info.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-x_info.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-x_info.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-x_info.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-x_info.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x_info.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_info.c
+x_info.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x_info.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x_info.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+x_info.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+x_info.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+x_info.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+x_info.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x_info.o: ../cryptlib.h x_info.c
 x_long.o: ../../e_os.h ../../include/openssl/asn1.h
 x_long.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 x_long.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
@@ -769,35 +780,37 @@
 x_name.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x_name.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x_name.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x_name.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x_name.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-x_name.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-x_name.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-x_name.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-x_name.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x_name.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_name.c
+x_name.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x_name.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x_name.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+x_name.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+x_name.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+x_name.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+x_name.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x_name.o: ../cryptlib.h x_name.c
 x_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
 x_pkey.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
 x_pkey.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 x_pkey.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x_pkey.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x_pkey.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x_pkey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x_pkey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-x_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-x_pkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-x_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-x_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_pkey.c
+x_pkey.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x_pkey.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x_pkey.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+x_pkey.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+x_pkey.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+x_pkey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+x_pkey.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x_pkey.o: ../cryptlib.h x_pkey.c
 x_pubkey.o: ../../e_os.h ../../include/openssl/asn1.h
 x_pubkey.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 x_pubkey.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 x_pubkey.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
 x_pubkey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 x_pubkey.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-x_pubkey.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-x_pubkey.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x_pubkey.o: ../../include/openssl/opensslconf.h
+x_pubkey.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+x_pubkey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x_pubkey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 x_pubkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x_pubkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
 x_pubkey.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
@@ -810,76 +823,82 @@
 x_req.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x_req.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x_req.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x_req.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x_req.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-x_req.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-x_req.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-x_req.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-x_req.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x_req.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_req.c
+x_req.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x_req.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x_req.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+x_req.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+x_req.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+x_req.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+x_req.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x_req.o: ../cryptlib.h x_req.c
 x_sig.o: ../../e_os.h ../../include/openssl/asn1.h
 x_sig.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 x_sig.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 x_sig.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x_sig.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x_sig.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x_sig.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x_sig.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-x_sig.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-x_sig.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-x_sig.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-x_sig.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x_sig.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_sig.c
+x_sig.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x_sig.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x_sig.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+x_sig.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+x_sig.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+x_sig.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+x_sig.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x_sig.o: ../cryptlib.h x_sig.c
 x_spki.o: ../../e_os.h ../../include/openssl/asn1.h
 x_spki.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 x_spki.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 x_spki.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x_spki.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x_spki.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x_spki.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x_spki.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-x_spki.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-x_spki.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-x_spki.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-x_spki.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x_spki.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_spki.c
+x_spki.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x_spki.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x_spki.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+x_spki.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+x_spki.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+x_spki.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+x_spki.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x_spki.o: ../cryptlib.h x_spki.c
 x_val.o: ../../e_os.h ../../include/openssl/asn1.h
 x_val.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 x_val.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 x_val.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x_val.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x_val.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x_val.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x_val.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-x_val.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-x_val.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-x_val.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-x_val.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x_val.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_val.c
+x_val.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x_val.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x_val.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+x_val.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+x_val.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+x_val.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+x_val.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x_val.o: ../cryptlib.h x_val.c
 x_x509.o: ../../e_os.h ../../include/openssl/asn1.h
 x_x509.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 x_x509.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
 x_x509.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 x_x509.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 x_x509.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-x_x509.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-x_x509.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x_x509.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-x_x509.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-x_x509.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-x_x509.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-x_x509.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-x_x509.o: ../../include/openssl/x509v3.h ../cryptlib.h x_x509.c
+x_x509.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+x_x509.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x_x509.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x_x509.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x_x509.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x_x509.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x_x509.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x_x509.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+x_x509.o: ../cryptlib.h x_x509.c
 x_x509a.o: ../../e_os.h ../../include/openssl/asn1.h
 x_x509a.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 x_x509a.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 x_x509a.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x_x509a.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x_x509a.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x_x509a.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x_x509a.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-x_x509a.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-x_x509a.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-x_x509a.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-x_x509a.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x_x509a.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_x509a.c
+x_x509a.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x_x509a.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x_x509a.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+x_x509a.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+x_x509a.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+x_x509a.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+x_x509a.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x_x509a.o: ../cryptlib.h x_x509a.c
diff --git a/crypto/asn1/a_bytes.c b/crypto/asn1/a_bytes.c
index 8d13f9c..92d630c 100644
--- a/crypto/asn1/a_bytes.c
+++ b/crypto/asn1/a_bytes.c
@@ -79,7 +79,7 @@
 
 	if (tag >= 32)
 		{
-		i=ASN1_R_TAG_VALUE_TOO_HIGH;;
+		i=ASN1_R_TAG_VALUE_TOO_HIGH;
 		goto err;
 		}
 	if (!(ASN1_tag2bit(tag) & type))
diff --git a/crypto/asn1/a_mbstr.c b/crypto/asn1/a_mbstr.c
index 2d4800a..1bcd046 100644
--- a/crypto/asn1/a_mbstr.c
+++ b/crypto/asn1/a_mbstr.c
@@ -1,5 +1,5 @@
 /* a_mbstr.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/asn1/a_sign.c b/crypto/asn1/a_sign.c
index 1081950..4dee45f 100644
--- a/crypto/asn1/a_sign.c
+++ b/crypto/asn1/a_sign.c
@@ -267,7 +267,12 @@
 		goto err;
 		}
 
-	EVP_SignInit_ex(&ctx,type, NULL);
+	if (!EVP_SignInit_ex(&ctx,type, NULL))
+		{
+		outl=0;
+		ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_EVP_LIB);
+		goto err;
+		}
 	EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl);
 	if (!EVP_SignFinal(&ctx,(unsigned char *)buf_out,
 			(unsigned int *)&outl,pkey))
diff --git a/crypto/asn1/a_strex.c b/crypto/asn1/a_strex.c
index c2dbb6f..7fc14d3 100644
--- a/crypto/asn1/a_strex.c
+++ b/crypto/asn1/a_strex.c
@@ -1,5 +1,5 @@
 /* a_strex.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/crypto/asn1/a_strnid.c b/crypto/asn1/a_strnid.c
index 613bbc4..fe515b5 100644
--- a/crypto/asn1/a_strnid.c
+++ b/crypto/asn1/a_strnid.c
@@ -1,5 +1,5 @@
 /* a_strnid.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/asn1/a_verify.c b/crypto/asn1/a_verify.c
index fdce6e4..da3efaa 100644
--- a/crypto/asn1/a_verify.c
+++ b/crypto/asn1/a_verify.c
@@ -100,7 +100,12 @@
 	p=buf_in;
 
 	i2d(data,&p);
-	EVP_VerifyInit_ex(&ctx,type, NULL);
+	if (!EVP_VerifyInit_ex(&ctx,type, NULL))
+		{
+		ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_EVP_LIB);
+		ret=0;
+		goto err;
+		}
 	EVP_VerifyUpdate(&ctx,(unsigned char *)buf_in,inl);
 
 	OPENSSL_cleanse(buf_in,(unsigned int)inl);
diff --git a/crypto/asn1/ameth_lib.c b/crypto/asn1/ameth_lib.c
new file mode 100644
index 0000000..18957c6
--- /dev/null
+++ b/crypto/asn1/ameth_lib.c
@@ -0,0 +1,446 @@
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/x509.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include "asn1_locl.h"
+
+extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
+extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[];
+extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
+
+/* Keep this sorted in type order !! */
+static const EVP_PKEY_ASN1_METHOD *standard_methods[] = 
+	{
+#ifndef OPENSSL_NO_RSA
+	&rsa_asn1_meths[0],
+	&rsa_asn1_meths[1],
+#endif
+#ifndef OPENSSL_NO_DH
+	&dh_asn1_meth,
+#endif
+#ifndef OPENSSL_NO_DSA
+	&dsa_asn1_meths[0],
+	&dsa_asn1_meths[1],
+	&dsa_asn1_meths[2],
+	&dsa_asn1_meths[3],
+	&dsa_asn1_meths[4],
+#endif
+#ifndef OPENSSL_NO_EC
+	&eckey_asn1_meth,
+#endif
+	&hmac_asn1_meth
+	};
+
+typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
+DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD)
+static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
+
+
+
+#ifdef TEST
+void main()
+	{
+	int i;
+	for (i = 0;
+		i < sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
+		i++)
+		fprintf(stderr, "Number %d id=%d (%s)\n", i,
+			standard_methods[i]->pkey_id,
+			OBJ_nid2sn(standard_methods[i]->pkey_id));
+	}
+#endif
+
+DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
+			   const EVP_PKEY_ASN1_METHOD *, ameth);
+
+static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a,
+		     const EVP_PKEY_ASN1_METHOD * const *b)
+	{
+        return ((*a)->pkey_id - (*b)->pkey_id);
+	}
+
+IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
+			     const EVP_PKEY_ASN1_METHOD *, ameth);
+
+int EVP_PKEY_asn1_get_count(void)
+	{
+	int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
+	if (app_methods)
+		num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
+	return num;
+	}
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
+	{
+	int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
+	if (idx < 0)
+		return NULL; 
+	if (idx < num)
+		return standard_methods[idx];
+	idx -= num;
+	return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
+	}
+
+static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
+	{
+	EVP_PKEY_ASN1_METHOD tmp;
+	const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
+	tmp.pkey_id = type;
+	if (app_methods)
+		{
+		int idx;
+		idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
+		if (idx >= 0)
+			return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
+		}
+	ret = OBJ_bsearch_ameth(&t, standard_methods,
+			  sizeof(standard_methods)
+			  /sizeof(EVP_PKEY_ASN1_METHOD *));
+	if (!ret || !*ret)
+		return NULL;
+	return *ret;
+	}
+
+/* Find an implementation of an ASN1 algorithm. If 'pe' is not NULL
+ * also search through engines and set *pe to a functional reference
+ * to the engine implementing 'type' or NULL if no engine implements 
+ * it.
+ */
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type)
+	{
+	const EVP_PKEY_ASN1_METHOD *t;
+	ENGINE *e;
+
+	for (;;)
+		{
+		t = pkey_asn1_find(type);
+		if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
+			break;
+		type = t->pkey_base_id;
+		}
+	if (pe)
+		{
+#ifndef OPENSSL_NO_ENGINE
+		/* type will contain the final unaliased type */
+		e = ENGINE_get_pkey_asn1_meth_engine(type);
+		if (e)
+			{
+			*pe = e;
+			return ENGINE_get_pkey_asn1_meth(e, type);
+			}
+#endif
+		*pe = NULL;
+		}
+	return t;
+	}
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
+					const char *str, int len)
+	{
+	int i;
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	if (len == -1)
+		len = strlen(str);
+	if (pe)
+		{
+#ifndef OPENSSL_NO_ENGINE
+		ENGINE *e;
+		ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
+		if (ameth)
+			{
+			/* Convert structural into
+			 * functional reference
+			 */
+			if (!ENGINE_init(e))
+				ameth = NULL;
+			ENGINE_free(e);
+			*pe = e;
+			return ameth;
+			}
+#endif
+		*pe = NULL;
+		}
+	for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
+		{
+		ameth = EVP_PKEY_asn1_get0(i);
+		if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
+			continue;
+		if (((int)strlen(ameth->pem_str) == len) && 
+			!strncasecmp(ameth->pem_str, str, len))
+			return ameth;
+		}
+	return NULL;
+	}
+
+int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
+	{
+	if (app_methods == NULL)
+		{
+		app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
+		if (!app_methods)
+			return 0;
+		}
+	if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
+		return 0;
+	sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
+	return 1;
+	}
+
+int EVP_PKEY_asn1_add_alias(int to, int from)
+	{
+	EVP_PKEY_ASN1_METHOD *ameth;
+	ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
+	if (!ameth)
+		return 0;
+	ameth->pkey_base_id = to;
+	return EVP_PKEY_asn1_add0(ameth);
+	}
+
+int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags,
+				const char **pinfo, const char **ppem_str,
+					const EVP_PKEY_ASN1_METHOD *ameth)
+	{
+	if (!ameth)
+		return 0;
+	if (ppkey_id)
+		*ppkey_id = ameth->pkey_id;
+	if (ppkey_base_id)
+		*ppkey_base_id = ameth->pkey_base_id;
+	if (ppkey_flags)
+		*ppkey_flags = ameth->pkey_flags;
+	if (pinfo)
+		*pinfo = ameth->info;
+	if (ppem_str)
+		*ppem_str = ameth->pem_str;
+	return 1;
+	}
+
+const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey)
+	{
+	return pkey->ameth;
+	}
+
+EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
+					const char *pem_str, const char *info)
+	{
+	EVP_PKEY_ASN1_METHOD *ameth;
+	ameth = OPENSSL_malloc(sizeof(EVP_PKEY_ASN1_METHOD));
+	if (!ameth)
+		return NULL;
+
+	ameth->pkey_id = id;
+	ameth->pkey_base_id = id;
+	ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
+
+	if (info)
+		{
+		ameth->info = BUF_strdup(info);
+		if (!ameth->info)
+			goto err;
+		}
+
+	if (pem_str)
+		{
+		ameth->pem_str = BUF_strdup(pem_str);
+		if (!ameth->pem_str)
+			goto err;
+		}
+
+	ameth->pub_decode = 0;
+	ameth->pub_encode = 0;
+	ameth->pub_cmp = 0;
+	ameth->pub_print = 0;
+
+	ameth->priv_decode = 0;
+	ameth->priv_encode = 0;
+	ameth->priv_print = 0;
+
+	ameth->old_priv_encode = 0;
+	ameth->old_priv_decode = 0;
+
+	ameth->pkey_size = 0;
+	ameth->pkey_bits = 0;
+
+	ameth->param_decode = 0;
+	ameth->param_encode = 0;
+	ameth->param_missing = 0;
+	ameth->param_copy = 0;
+	ameth->param_cmp = 0;
+	ameth->param_print = 0;
+
+	ameth->pkey_free = 0;
+	ameth->pkey_ctrl = 0;
+
+	return ameth;
+
+	err:
+
+	EVP_PKEY_asn1_free(ameth);
+	return NULL;
+
+	}
+
+void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, 
+			const EVP_PKEY_ASN1_METHOD *src)
+	{
+
+	dst->pub_decode = src->pub_decode;
+	dst->pub_encode = src->pub_encode;
+	dst->pub_cmp = src->pub_cmp;
+	dst->pub_print = src->pub_print;
+
+	dst->priv_decode = src->priv_decode;
+	dst->priv_encode = src->priv_encode;
+	dst->priv_print = src->priv_print;
+
+	dst->old_priv_encode = src->old_priv_encode;
+	dst->old_priv_decode = src->old_priv_decode;
+
+	dst->pkey_size = src->pkey_size;
+	dst->pkey_bits = src->pkey_bits;
+
+	dst->param_decode = src->param_decode;
+	dst->param_encode = src->param_encode;
+	dst->param_missing = src->param_missing;
+	dst->param_copy = src->param_copy;
+	dst->param_cmp = src->param_cmp;
+	dst->param_print = src->param_print;
+
+	dst->pkey_free = src->pkey_free;
+	dst->pkey_ctrl = src->pkey_ctrl;
+
+	}
+
+void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
+	{
+	if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC))
+		{
+		if (ameth->pem_str)
+			OPENSSL_free(ameth->pem_str);
+		if (ameth->info)
+			OPENSSL_free(ameth->info);
+		OPENSSL_free(ameth);
+		}
+	}
+
+void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
+		int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub),
+		int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk),
+		int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
+		int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *pctx),
+		int (*pkey_size)(const EVP_PKEY *pk),
+		int (*pkey_bits)(const EVP_PKEY *pk))
+	{
+	ameth->pub_decode = pub_decode;
+	ameth->pub_encode = pub_encode;
+	ameth->pub_cmp = pub_cmp;
+	ameth->pub_print = pub_print;
+	ameth->pkey_size = pkey_size;
+	ameth->pkey_bits = pkey_bits;
+	}
+
+void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
+		int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf),
+		int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk),
+		int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *pctx))
+	{
+	ameth->priv_decode = priv_decode;
+	ameth->priv_encode = priv_encode;
+	ameth->priv_print = priv_print;
+	}
+
+void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
+		int (*param_decode)(EVP_PKEY *pkey,
+				const unsigned char **pder, int derlen),
+		int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder),
+		int (*param_missing)(const EVP_PKEY *pk),
+		int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from),
+		int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
+		int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *pctx))
+	{
+	ameth->param_decode = param_decode;
+	ameth->param_encode = param_encode;
+	ameth->param_missing = param_missing;
+	ameth->param_copy = param_copy;
+	ameth->param_cmp = param_cmp;
+	ameth->param_print = param_print;
+	}
+
+void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
+		void (*pkey_free)(EVP_PKEY *pkey))
+	{
+	ameth->pkey_free = pkey_free;
+	}
+
+void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
+		int (*pkey_ctrl)(EVP_PKEY *pkey, int op,
+							long arg1, void *arg2))
+	{
+	ameth->pkey_ctrl = pkey_ctrl;
+	}
diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h
index 424cd34..e338522 100644
--- a/crypto/asn1/asn1.h
+++ b/crypto/asn1/asn1.h
@@ -612,6 +612,7 @@
 			B_ASN1_GENERALIZEDTIME
 
 #define B_ASN1_PRINTABLE \
+			B_ASN1_NUMERICSTRING| \
 			B_ASN1_PRINTABLESTRING| \
 			B_ASN1_T61STRING| \
 			B_ASN1_IA5STRING| \
@@ -1217,6 +1218,7 @@
 #define ASN1_R_BAD_OBJECT_HEADER			 102
 #define ASN1_R_BAD_PASSWORD_READ			 103
 #define ASN1_R_BAD_TAG					 104
+#define ASN1_R_BMPSTRING_IS_WRONG_LENGTH		 210
 #define ASN1_R_BN_LIB					 105
 #define ASN1_R_BOOLEAN_IS_WRONG_LENGTH			 106
 #define ASN1_R_BUFFER_TOO_SMALL				 107
@@ -1306,6 +1308,7 @@
 #define ASN1_R_UNABLE_TO_DECODE_RSA_KEY			 157
 #define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY		 158
 #define ASN1_R_UNEXPECTED_EOC				 159
+#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH		 211
 #define ASN1_R_UNKNOWN_FORMAT				 160
 #define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM		 161
 #define ASN1_R_UNKNOWN_OBJECT_TYPE			 162
diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c
index f8a3e2e..5f5de98 100644
--- a/crypto/asn1/asn1_err.c
+++ b/crypto/asn1/asn1_err.c
@@ -195,6 +195,7 @@
 {ERR_REASON(ASN1_R_BAD_OBJECT_HEADER)    ,"bad object header"},
 {ERR_REASON(ASN1_R_BAD_PASSWORD_READ)    ,"bad password read"},
 {ERR_REASON(ASN1_R_BAD_TAG)              ,"bad tag"},
+{ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH),"bmpstring is wrong length"},
 {ERR_REASON(ASN1_R_BN_LIB)               ,"bn lib"},
 {ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH),"boolean is wrong length"},
 {ERR_REASON(ASN1_R_BUFFER_TOO_SMALL)     ,"buffer too small"},
@@ -284,6 +285,7 @@
 {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY),"unable to decode rsa key"},
 {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY),"unable to decode rsa private key"},
 {ERR_REASON(ASN1_R_UNEXPECTED_EOC)       ,"unexpected eoc"},
+{ERR_REASON(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH),"universalstring is wrong length"},
 {ERR_REASON(ASN1_R_UNKNOWN_FORMAT)       ,"unknown format"},
 {ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM),"unknown message digest algorithm"},
 {ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE)  ,"unknown object type"},
diff --git a/crypto/asn1/asn1_gen.c b/crypto/asn1/asn1_gen.c
index 26c8327..2da3829 100644
--- a/crypto/asn1/asn1_gen.c
+++ b/crypto/asn1/asn1_gen.c
@@ -1,5 +1,5 @@
 /* asn1_gen.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2002.
  */
 /* ====================================================================
diff --git a/crypto/asn1/asn1_locl.h b/crypto/asn1/asn1_locl.h
new file mode 100644
index 0000000..5aa65e2
--- /dev/null
+++ b/crypto/asn1/asn1_locl.h
@@ -0,0 +1,134 @@
+/* asn1t.h */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2006.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Internal ASN1 structures and functions: not for application use */
+
+/* ASN1 print context structure */
+
+struct asn1_pctx_st
+	{
+	unsigned long flags;
+	unsigned long nm_flags;
+	unsigned long cert_flags;
+	unsigned long oid_flags;
+	unsigned long str_flags;
+	} /* ASN1_PCTX */;
+
+/* ASN1 public key method structure */
+
+struct evp_pkey_asn1_method_st
+	{
+	int pkey_id;
+	int pkey_base_id;
+	unsigned long pkey_flags;
+
+	char *pem_str;
+	char *info;
+
+	int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub);
+	int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk);
+	int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
+	int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *pctx);
+
+	int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf);
+	int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk);
+	int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *pctx);
+
+	int (*pkey_size)(const EVP_PKEY *pk);
+	int (*pkey_bits)(const EVP_PKEY *pk);
+
+	int (*param_decode)(EVP_PKEY *pkey,
+				const unsigned char **pder, int derlen);
+	int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder);
+	int (*param_missing)(const EVP_PKEY *pk);
+	int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from);
+	int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
+	int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
+							ASN1_PCTX *pctx);
+
+	void (*pkey_free)(EVP_PKEY *pkey);
+	int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2);
+
+	/* Legacy functions for old PEM */
+
+	int (*old_priv_decode)(EVP_PKEY *pkey,
+				const unsigned char **pder, int derlen);
+	int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder);
+
+	} /* EVP_PKEY_ASN1_METHOD */;
+
+/* Method to handle CRL access.
+ * In general a CRL could be very large (several Mb) and can consume large
+ * amounts of resources if stored in memory by multiple processes.
+ * This method allows general CRL operations to be redirected to more
+ * efficient callbacks: for example a CRL entry database.
+ */
+
+#define X509_CRL_METHOD_DYNAMIC		1
+
+struct x509_crl_method_st
+	{
+	int flags;
+	int (*crl_init)(X509_CRL *crl);
+	int (*crl_free)(X509_CRL *crl);
+	int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
+				ASN1_INTEGER *ser, X509_NAME *issuer);
+	int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk);
+	};
diff --git a/crypto/asn1/asn1_par.c b/crypto/asn1/asn1_par.c
index 501b62a..8657f73 100644
--- a/crypto/asn1/asn1_par.c
+++ b/crypto/asn1/asn1_par.c
@@ -213,6 +213,8 @@
 				(tag == V_ASN1_T61STRING) ||
 				(tag == V_ASN1_IA5STRING) ||
 				(tag == V_ASN1_VISIBLESTRING) ||
+				(tag == V_ASN1_NUMERICSTRING) ||
+				(tag == V_ASN1_UTF8STRING) ||
 				(tag == V_ASN1_UTCTIME) ||
 				(tag == V_ASN1_GENERALIZEDTIME))
 				{
diff --git a/crypto/asn1/asn1t.h b/crypto/asn1/asn1t.h
index bf315e6..ac14f94 100644
--- a/crypto/asn1/asn1t.h
+++ b/crypto/asn1/asn1t.h
@@ -1,5 +1,5 @@
 /* asn1t.h */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/crypto/asn1/asn_mime.c b/crypto/asn1/asn_mime.c
index fe7c4ec..d8d9e76 100644
--- a/crypto/asn1/asn_mime.c
+++ b/crypto/asn1/asn_mime.c
@@ -152,7 +152,6 @@
 
 static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
 	{
-	const EVP_MD *md;
 	int i, have_unknown = 0, write_comma, md_nid;
 	have_unknown = 0;
 	write_comma = 0;
@@ -162,7 +161,6 @@
 			BIO_write(out, ",", 1);
 		write_comma = 1;
 		md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm);
-		md = EVP_get_digestbynid(md_nid);
 		switch(md_nid)
 			{
 			case NID_sha1:
@@ -526,6 +524,8 @@
 	sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
 	while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)
 						BIO_write(out, iobuf, len);
+	if (len < 0)
+		return 0;
 	return 1;
 }
 
diff --git a/crypto/asn1/asn_moid.c b/crypto/asn1/asn_moid.c
index 9132350..1ea6a59 100644
--- a/crypto/asn1/asn_moid.c
+++ b/crypto/asn1/asn_moid.c
@@ -1,5 +1,5 @@
 /* asn_moid.c */
-/* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
  * project 2001.
  */
 /* ====================================================================
diff --git a/crypto/asn1/asn_pack.c b/crypto/asn1/asn_pack.c
index e8b671b..f1a5a05 100644
--- a/crypto/asn1/asn_pack.c
+++ b/crypto/asn1/asn_pack.c
@@ -1,5 +1,5 @@
 /* asn_pack.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/asn1/bio_asn1.c b/crypto/asn1/bio_asn1.c
new file mode 100644
index 0000000..dc7efd5
--- /dev/null
+++ b/crypto/asn1/bio_asn1.c
@@ -0,0 +1,495 @@
+/* bio_asn1.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2006 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/* Experimental ASN1 BIO. When written through the data is converted
+ * to an ASN1 string type: default is OCTET STRING. Additional functions
+ * can be provided to add prefix and suffix data.
+ */
+
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+
+/* Must be large enough for biggest tag+length */
+#define DEFAULT_ASN1_BUF_SIZE 20
+
+typedef enum 
+	{
+	ASN1_STATE_START,
+	ASN1_STATE_PRE_COPY,
+	ASN1_STATE_HEADER,
+	ASN1_STATE_HEADER_COPY,
+	ASN1_STATE_DATA_COPY,
+	ASN1_STATE_POST_COPY,
+	ASN1_STATE_DONE
+	} asn1_bio_state_t;
+
+typedef struct BIO_ASN1_EX_FUNCS_st
+	{
+	asn1_ps_func	*ex_func;
+	asn1_ps_func	*ex_free_func;
+	} BIO_ASN1_EX_FUNCS;
+
+typedef struct BIO_ASN1_BUF_CTX_t
+	{
+	/* Internal state */
+	asn1_bio_state_t state;
+	/* Internal buffer */
+	unsigned char *buf;
+	/* Size of buffer */
+	int bufsize;
+	/* Current position in buffer */
+	int bufpos;
+	/* Current buffer length */
+	int buflen;
+	/* Amount of data to copy */
+	int copylen;
+	/* Class and tag to use */
+	int asn1_class, asn1_tag;
+	asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
+	/* Extra buffer for prefix and suffix data */
+	unsigned char *ex_buf;
+	int ex_len;
+	int ex_pos;
+	void *ex_arg;
+	} BIO_ASN1_BUF_CTX;
+
+
+static int asn1_bio_write(BIO *h, const char *buf,int num);
+static int asn1_bio_read(BIO *h, char *buf, int size);
+static int asn1_bio_puts(BIO *h, const char *str);
+static int asn1_bio_gets(BIO *h, char *str, int size);
+static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int asn1_bio_new(BIO *h);
+static int asn1_bio_free(BIO *data);
+static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
+static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+				asn1_ps_func *cleanup, asn1_bio_state_t next);
+static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+				asn1_ps_func *setup, 
+				asn1_bio_state_t ex_state,
+				asn1_bio_state_t other_state);
+
+static BIO_METHOD methods_asn1=
+	{
+	BIO_TYPE_ASN1,
+	"asn1",
+	asn1_bio_write,
+	asn1_bio_read,
+	asn1_bio_puts,
+	asn1_bio_gets,
+	asn1_bio_ctrl,
+	asn1_bio_new,
+	asn1_bio_free,
+	asn1_bio_callback_ctrl,
+	};
+
+BIO_METHOD *BIO_f_asn1(void)
+	{
+	return(&methods_asn1);
+	}
+
+
+static int asn1_bio_new(BIO *b)
+	{
+	BIO_ASN1_BUF_CTX *ctx;
+	ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX));
+	if (!ctx)
+		return 0;
+	if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE))
+		return 0;
+	b->init = 1;
+	b->ptr = (char *)ctx;
+	b->flags = 0;
+	return 1;
+	}
+
+static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
+	{
+	ctx->buf = OPENSSL_malloc(size);
+	if (!ctx->buf)
+		return 0;
+	ctx->bufsize = size;
+	ctx->bufpos = 0;
+	ctx->buflen = 0;
+	ctx->copylen = 0;
+	ctx->asn1_class = V_ASN1_UNIVERSAL;
+	ctx->asn1_tag = V_ASN1_OCTET_STRING;
+	ctx->ex_buf = 0;
+	ctx->ex_pos = 0;
+	ctx->ex_len = 0;
+	ctx->state = ASN1_STATE_START;
+	return 1;
+	}
+
+static int asn1_bio_free(BIO *b)
+	{
+	BIO_ASN1_BUF_CTX *ctx;
+	ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
+	if (ctx == NULL)
+		return 0;
+	if (ctx->buf)
+		OPENSSL_free(ctx->buf);
+	OPENSSL_free(ctx);
+	b->init = 0;
+	b->ptr = NULL;
+	b->flags = 0;
+	return 1;
+	}
+
+static int asn1_bio_write(BIO *b, const char *in , int inl)
+	{
+	BIO_ASN1_BUF_CTX *ctx;
+	int wrmax, wrlen, ret;
+	unsigned char *p;
+	if (!in || (inl < 0) || (b->next_bio == NULL))
+		return 0;
+	ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
+	if (ctx == NULL)
+		return 0;
+
+	wrlen = 0;
+	ret = -1;
+
+	for(;;)
+		{
+		switch (ctx->state)
+			{
+
+			/* Setup prefix data, call it */
+			case ASN1_STATE_START:
+			if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
+				ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
+				return 0;
+			break;
+
+			/* Copy any pre data first */
+			case ASN1_STATE_PRE_COPY:
+
+			ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
+							ASN1_STATE_HEADER);
+
+			if (ret <= 0)
+				goto done;
+
+			break;
+
+			case ASN1_STATE_HEADER:
+			ctx->buflen =
+				ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
+			OPENSSL_assert(ctx->buflen <= ctx->bufsize);
+			p = ctx->buf;
+			ASN1_put_object(&p, 0, inl,
+					ctx->asn1_tag, ctx->asn1_class);
+			ctx->copylen = inl;
+			ctx->state = ASN1_STATE_HEADER_COPY;
+
+			break;
+
+			case ASN1_STATE_HEADER_COPY:	
+			ret = BIO_write(b->next_bio,
+					ctx->buf + ctx->bufpos, ctx->buflen);
+			if (ret <= 0)
+				goto done;
+
+			ctx->buflen -= ret;
+			if (ctx->buflen)
+				ctx->bufpos += ret;
+			else
+				{
+				ctx->bufpos = 0;
+				ctx->state = ASN1_STATE_DATA_COPY;
+				}
+
+			break;
+
+			case ASN1_STATE_DATA_COPY:
+
+			if (inl > ctx->copylen)
+				wrmax = ctx->copylen;
+			else
+				wrmax = inl;
+			ret = BIO_write(b->next_bio, in, wrmax);
+			if (ret <= 0)
+				break;
+			wrlen += ret;
+			ctx->copylen -= ret;
+			in += ret;
+			inl -= ret;
+
+			if (ctx->copylen == 0)
+				ctx->state = ASN1_STATE_HEADER;
+
+			if (inl == 0)
+				goto done;
+
+			break;
+
+			default:
+			BIO_clear_retry_flags(b);
+			return 0;
+
+			}
+
+		}
+
+	done:
+	BIO_clear_retry_flags(b);
+	BIO_copy_next_retry(b);
+
+	return (wrlen > 0) ? wrlen : ret;
+
+	}
+
+static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+				asn1_ps_func *cleanup, asn1_bio_state_t next)
+	{
+	int ret;
+	if (ctx->ex_len <= 0)
+		return 1;
+	for(;;)
+		{
+		ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos,
+								ctx->ex_len);
+		if (ret <= 0)
+			break;
+		ctx->ex_len -= ret;
+		if (ctx->ex_len > 0)
+			ctx->ex_pos += ret;
+		else
+			{
+			if(cleanup)
+				cleanup(b, &ctx->ex_buf, &ctx->ex_len,
+								&ctx->ex_arg);
+			ctx->state = next;
+			ctx->ex_pos = 0;
+			break;
+			}
+		}
+	return ret;
+	}
+
+static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+				asn1_ps_func *setup, 
+				asn1_bio_state_t ex_state,
+				asn1_bio_state_t other_state)
+	{
+	if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg))
+		{
+		BIO_clear_retry_flags(b);
+		return 0;
+		}
+	if (ctx->ex_len > 0)
+		ctx->state = ex_state;
+	else
+		ctx->state = other_state;
+	return 1;
+	}
+
+static int asn1_bio_read(BIO *b, char *in , int inl)
+	{
+	if (!b->next_bio)
+		return 0;
+	return BIO_read(b->next_bio, in , inl);
+	}
+
+static int asn1_bio_puts(BIO *b, const char *str)
+	{
+	return asn1_bio_write(b, str, strlen(str));
+	}
+
+static int asn1_bio_gets(BIO *b, char *str, int size)
+	{
+	if (!b->next_bio)
+		return 0;
+	return BIO_gets(b->next_bio, str , size);
+	}
+
+static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+	{
+	if (b->next_bio == NULL) return(0);
+	return BIO_callback_ctrl(b->next_bio,cmd,fp);
+	}
+
+static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
+	{
+	BIO_ASN1_BUF_CTX *ctx;
+	BIO_ASN1_EX_FUNCS *ex_func;
+	long ret = 1;
+	ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
+	if (ctx == NULL)
+		return 0;
+	switch(cmd)
+		{
+
+		case BIO_C_SET_PREFIX:
+		ex_func = arg2;
+		ctx->prefix  = ex_func->ex_func;
+		ctx->prefix_free  = ex_func->ex_free_func;
+		break;
+
+		case BIO_C_GET_PREFIX:
+		ex_func = arg2;
+		ex_func->ex_func = ctx->prefix;
+		ex_func->ex_free_func = ctx->prefix_free;
+		break;
+
+		case BIO_C_SET_SUFFIX:
+		ex_func = arg2;
+		ctx->suffix  = ex_func->ex_func;
+		ctx->suffix_free  = ex_func->ex_free_func;
+		break;
+
+		case BIO_C_GET_SUFFIX:
+		ex_func = arg2;
+		ex_func->ex_func = ctx->suffix;
+		ex_func->ex_free_func = ctx->suffix_free;
+		break;
+
+		case BIO_C_SET_EX_ARG:
+		ctx->ex_arg = arg2;
+		break;
+
+		case BIO_C_GET_EX_ARG:
+		*(void **)arg2 = ctx->ex_arg;
+		break;
+
+		case BIO_CTRL_FLUSH:
+		if (!b->next_bio)
+			return 0;
+
+		/* Call post function if possible */
+		if (ctx->state == ASN1_STATE_HEADER)
+			{
+			if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
+				ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
+				return 0;
+			}
+
+		if (ctx->state == ASN1_STATE_POST_COPY)
+			{
+			ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
+							ASN1_STATE_DONE);
+			if (ret <= 0)
+				return ret;
+			}
+
+		if (ctx->state == ASN1_STATE_DONE)
+			return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
+		else
+			{
+			BIO_clear_retry_flags(b);
+			return 0;
+			}
+		break;
+
+
+		default:
+		if (!b->next_bio)
+			return 0;
+		return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
+
+		}
+
+	return ret;
+	}
+
+static int asn1_bio_set_ex(BIO *b, int cmd,
+		asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
+	{
+	BIO_ASN1_EX_FUNCS extmp;
+	extmp.ex_func = ex_func;
+	extmp.ex_free_func = ex_free_func;
+	return BIO_ctrl(b, cmd, 0, &extmp);
+	}
+
+static int asn1_bio_get_ex(BIO *b, int cmd,
+		asn1_ps_func **ex_func, asn1_ps_func **ex_free_func)
+	{
+	BIO_ASN1_EX_FUNCS extmp;
+	int ret;
+	ret = BIO_ctrl(b, cmd, 0, &extmp);
+	if (ret > 0)
+		{
+		*ex_func = extmp.ex_func;
+		*ex_free_func = extmp.ex_free_func;
+		}
+	return ret;
+	}
+
+int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, asn1_ps_func *prefix_free)
+	{
+	return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
+	}
+
+int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, asn1_ps_func **pprefix_free)
+	{
+	return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
+	}
+
+int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, asn1_ps_func *suffix_free)
+	{
+	return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
+	}
+
+int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_func **psuffix_free)
+	{
+	return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
+	}
diff --git a/crypto/asn1/bio_ndef.c b/crypto/asn1/bio_ndef.c
new file mode 100644
index 0000000..370389b
--- /dev/null
+++ b/crypto/asn1/bio_ndef.c
@@ -0,0 +1,246 @@
+/* bio_ndef.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/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+
+#ifndef OPENSSL_SYSNAME_NETWARE
+#include <memory.h>
+#endif
+#include <stdio.h>
+
+/* Experimental NDEF ASN1 BIO support routines */
+
+/* The usage is quite simple, initialize an ASN1 structure,
+ * get a BIO from it then any data written through the BIO
+ * will end up translated to approptiate format on the fly.
+ * The data is streamed out and does *not* need to be
+ * all held in memory at once.
+ *
+ * When the BIO is flushed the output is finalized and any
+ * signatures etc written out.
+ *
+ * The BIO is a 'proper' BIO and can handle non blocking I/O
+ * correctly.
+ *
+ * The usage is simple. The implementation is *not*...
+ */
+
+/* BIO support data stored in the ASN1 BIO ex_arg */
+
+typedef struct ndef_aux_st
+	{
+	/* ASN1 structure this BIO refers to */
+	ASN1_VALUE *val;
+	const ASN1_ITEM *it;
+	/* Top of the BIO chain */
+	BIO *ndef_bio;
+	/* Output BIO */
+	BIO *out;
+	/* Boundary where content is inserted */
+	unsigned char **boundary;
+	/* DER buffer start */
+	unsigned char *derbuf;
+	} NDEF_SUPPORT;
+
+static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+
+BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
+	{
+	NDEF_SUPPORT *ndef_aux = NULL;
+	BIO *asn_bio = NULL;
+	const ASN1_AUX *aux = it->funcs;
+	ASN1_STREAM_ARG sarg;
+
+	if (!aux || !aux->asn1_cb)
+		{
+		ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
+		return NULL;
+		}
+	ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
+	asn_bio = BIO_new(BIO_f_asn1());
+
+	/* ASN1 bio needs to be next to output BIO */
+
+	out = BIO_push(asn_bio, out);
+
+	if (!ndef_aux || !asn_bio || !out)
+		goto err;
+
+	BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
+	BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
+
+	/* Now let callback prepend any digest, cipher etc BIOs
+	 * ASN1 structure needs.
+	 */
+
+	sarg.out = out;
+	sarg.ndef_bio = NULL;
+	sarg.boundary = NULL;
+
+	if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
+		goto err;
+
+	ndef_aux->val = val;
+	ndef_aux->it = it;
+	ndef_aux->ndef_bio = sarg.ndef_bio;
+	ndef_aux->boundary = sarg.boundary;
+	ndef_aux->out = out;
+
+	BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
+
+	return sarg.ndef_bio;
+
+	err:
+	if (asn_bio)
+		BIO_free(asn_bio);
+	if (ndef_aux)
+		OPENSSL_free(ndef_aux);
+	return NULL;
+	}
+
+static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+	{
+	NDEF_SUPPORT *ndef_aux;
+	unsigned char *p;
+	int derlen;
+
+	if (!parg)
+		return 0;
+
+	ndef_aux = *(NDEF_SUPPORT **)parg;
+
+	derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+	p = OPENSSL_malloc(derlen);
+	ndef_aux->derbuf = p;
+	*pbuf = p;
+	derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+
+	if (!*ndef_aux->boundary)
+		return 0;
+
+	*plen = *ndef_aux->boundary - *pbuf;
+
+	return 1;
+	}
+
+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+	{
+	NDEF_SUPPORT *ndef_aux;
+
+	if (!parg)
+		return 0;
+
+	ndef_aux = *(NDEF_SUPPORT **)parg;
+
+	if (ndef_aux->derbuf)
+		OPENSSL_free(ndef_aux->derbuf);
+
+	ndef_aux->derbuf = NULL;
+	*pbuf = NULL;
+	*plen = 0;
+	return 1;
+	}
+
+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+	{
+	NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
+	if (!ndef_prefix_free(b, pbuf, plen, parg))
+		return 0;
+	OPENSSL_free(*pndef_aux);
+	*pndef_aux = NULL;
+	return 1;
+	}
+
+static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+	{
+	NDEF_SUPPORT *ndef_aux;
+	unsigned char *p;
+	int derlen;
+	const ASN1_AUX *aux;
+	ASN1_STREAM_ARG sarg;
+
+	if (!parg)
+		return 0;
+
+	ndef_aux = *(NDEF_SUPPORT **)parg;
+
+	aux = ndef_aux->it->funcs;
+
+	/* Finalize structures */
+	sarg.ndef_bio = ndef_aux->ndef_bio;
+	sarg.out = ndef_aux->out;
+	sarg.boundary = ndef_aux->boundary;
+	if (aux->asn1_cb(ASN1_OP_STREAM_POST,
+				&ndef_aux->val, ndef_aux->it, &sarg) <= 0)
+		return 0;
+
+	derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+	p = OPENSSL_malloc(derlen);
+	ndef_aux->derbuf = p;
+	*pbuf = p;
+	derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+
+	if (!*ndef_aux->boundary)
+		return 0;
+	*pbuf = *ndef_aux->boundary;
+	*plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
+
+	return 1;
+	}
diff --git a/crypto/asn1/nsseq.c b/crypto/asn1/nsseq.c
index 50e2d4d..e551c57 100644
--- a/crypto/asn1/nsseq.c
+++ b/crypto/asn1/nsseq.c
@@ -1,5 +1,5 @@
 /* nsseq.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/asn1/p5_pbe.c b/crypto/asn1/p5_pbe.c
index da91170..c4582f8 100644
--- a/crypto/asn1/p5_pbe.c
+++ b/crypto/asn1/p5_pbe.c
@@ -1,5 +1,5 @@
 /* p5_pbe.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/asn1/p5_pbev2.c b/crypto/asn1/p5_pbev2.c
index c834a38..2b0516a 100644
--- a/crypto/asn1/p5_pbev2.c
+++ b/crypto/asn1/p5_pbev2.c
@@ -1,5 +1,5 @@
 /* p5_pbev2.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999-2004.
  */
 /* ====================================================================
diff --git a/crypto/asn1/p8_pkey.c b/crypto/asn1/p8_pkey.c
index 24b4091..0a19575 100644
--- a/crypto/asn1/p8_pkey.c
+++ b/crypto/asn1/p8_pkey.c
@@ -1,5 +1,5 @@
 /* p8_pkey.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/asn1/t_bitst.c b/crypto/asn1/t_bitst.c
index 397332d..2e59a25 100644
--- a/crypto/asn1/t_bitst.c
+++ b/crypto/asn1/t_bitst.c
@@ -1,5 +1,5 @@
 /* t_bitst.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/asn1/t_crl.c b/crypto/asn1/t_crl.c
index 929b3e5..bdb244c 100644
--- a/crypto/asn1/t_crl.c
+++ b/crypto/asn1/t_crl.c
@@ -1,5 +1,5 @@
 /* t_crl.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/asn1/t_spki.c b/crypto/asn1/t_spki.c
index c2a5797..a73369b 100644
--- a/crypto/asn1/t_spki.c
+++ b/crypto/asn1/t_spki.c
@@ -1,5 +1,5 @@
 /* t_spki.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/asn1/t_x509.c b/crypto/asn1/t_x509.c
index eb776b7..8f746f9 100644
--- a/crypto/asn1/t_x509.c
+++ b/crypto/asn1/t_x509.c
@@ -332,7 +332,7 @@
 int ASN1_STRING_print(BIO *bp, ASN1_STRING *v)
 	{
 	int i,n;
-	char buf[80],*p;;
+	char buf[80],*p;
 
 	if (v == NULL) return(0);
 	n=0;
@@ -393,8 +393,9 @@
 	d= (v[6]-'0')*10+(v[7]-'0');
 	h= (v[8]-'0')*10+(v[9]-'0');
 	m=  (v[10]-'0')*10+(v[11]-'0');
-	if (	(v[12] >= '0') && (v[12] <= '9') &&
-		(v[13] >= '0') && (v[13] <= '9'))
+	if (tm->length >= 14 &&
+	    (v[12] >= '0') && (v[12] <= '9') &&
+	    (v[13] >= '0') && (v[13] <= '9'))
 		s=  (v[12]-'0')*10+(v[13]-'0');
 
 	if (BIO_printf(bp,"%s %2d %02d:%02d:%02d %d%s",
@@ -428,8 +429,9 @@
 	d= (v[4]-'0')*10+(v[5]-'0');
 	h= (v[6]-'0')*10+(v[7]-'0');
 	m=  (v[8]-'0')*10+(v[9]-'0');
-	if (	(v[10] >= '0') && (v[10] <= '9') &&
-		(v[11] >= '0') && (v[11] <= '9'))
+	if (tm->length >=12 &&
+	    (v[10] >= '0') && (v[10] <= '9') &&
+	    (v[11] >= '0') && (v[11] <= '9'))
 		s=  (v[10]-'0')*10+(v[11]-'0');
 
 	if (BIO_printf(bp,"%s %2d %02d:%02d:%02d %d%s",
@@ -501,4 +503,3 @@
 	OPENSSL_free(b);
 	return(ret);
 	}
-
diff --git a/crypto/asn1/t_x509a.c b/crypto/asn1/t_x509a.c
index ffbbfb5..8b18801 100644
--- a/crypto/asn1/t_x509a.c
+++ b/crypto/asn1/t_x509a.c
@@ -1,5 +1,5 @@
 /* t_x509a.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c
index 0ee4062..48bc1c0 100644
--- a/crypto/asn1/tasn_dec.c
+++ b/crypto/asn1/tasn_dec.c
@@ -1,5 +1,5 @@
 /* tasn_dec.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
@@ -69,7 +69,7 @@
 static int asn1_find_end(const unsigned char **in, long len, char inf);
 
 static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
-				char inf, int tag, int aclass);
+			char inf, int tag, int aclass, int depth);
 
 static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen);
 
@@ -611,7 +611,6 @@
 
 	err:
 	ASN1_template_free(val, tt);
-	*val = NULL;
 	return 0;
 	}
 
@@ -758,7 +757,6 @@
 
 	err:
 	ASN1_template_free(val, tt);
-	*val = NULL;
 	return 0;
 	}
 
@@ -878,7 +876,7 @@
 		 * internally irrespective of the type. So instead just check
 		 * for UNIVERSAL class and ignore the tag.
 		 */
-		if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL))
+		if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0))
 			{
 			free_cont = 1;
 			goto err;
@@ -1012,6 +1010,18 @@
 		case V_ASN1_SET:
 		case V_ASN1_SEQUENCE:
 		default:
+		if (utype == V_ASN1_BMPSTRING && (len & 1))
+			{
+			ASN1err(ASN1_F_ASN1_EX_C2I,
+					ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
+			goto err;
+			}
+		if (utype == V_ASN1_UNIVERSALSTRING && (len & 3))
+			{
+			ASN1err(ASN1_F_ASN1_EX_C2I,
+					ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
+			goto err;
+			}
 		/* All based on ASN1_STRING and handled the same */
 		if (!*pval)
 			{
@@ -1128,8 +1138,18 @@
  * if it is indefinite length.
  */
 
+#ifndef ASN1_MAX_STRING_NEST
+/* This determines how many levels of recursion are permitted in ASN1
+ * string types. If it is not limited stack overflows can occur. If set
+ * to zero no recursion is allowed at all. Although zero should be adequate
+ * examples exist that require a value of 1. So 5 should be more than enough.
+ */
+#define ASN1_MAX_STRING_NEST 5
+#endif
+
+
 static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
-				char inf, int tag, int aclass)
+			char inf, int tag, int aclass, int depth)
 	{
 	const unsigned char *p, *q;
 	long plen;
@@ -1171,13 +1191,15 @@
 		/* If indefinite length constructed update max length */
 		if (cst)
 			{
-#ifdef OPENSSL_ALLOW_NESTED_ASN1_STRINGS
-			if (!asn1_collect(buf, &p, plen, ininf, tag, aclass))
+			if (depth >= ASN1_MAX_STRING_NEST)
+				{
+				ASN1err(ASN1_F_ASN1_COLLECT,
+					ASN1_R_NESTED_ASN1_STRING);
 				return 0;
-#else
-			ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_NESTED_ASN1_STRING);
-			return 0;
-#endif
+				}
+			if (!asn1_collect(buf, &p, plen, ininf, tag, aclass,
+						depth + 1))
+				return 0;
 			}
 		else if (plen && !collect_data(buf, &p, plen))
 			return 0;
diff --git a/crypto/asn1/tasn_enc.c b/crypto/asn1/tasn_enc.c
index be19b36..2721f90 100644
--- a/crypto/asn1/tasn_enc.c
+++ b/crypto/asn1/tasn_enc.c
@@ -1,5 +1,5 @@
 /* tasn_enc.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/crypto/asn1/tasn_fre.c b/crypto/asn1/tasn_fre.c
index bb7c1e2..d7c017f 100644
--- a/crypto/asn1/tasn_fre.c
+++ b/crypto/asn1/tasn_fre.c
@@ -1,5 +1,5 @@
 /* tasn_fre.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/crypto/asn1/tasn_new.c b/crypto/asn1/tasn_new.c
index 531dad3..5c6a2eb 100644
--- a/crypto/asn1/tasn_new.c
+++ b/crypto/asn1/tasn_new.c
@@ -1,5 +1,5 @@
 /* tasn_new.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/crypto/asn1/tasn_prn.c b/crypto/asn1/tasn_prn.c
index 719639b..b9c96a6 100644
--- a/crypto/asn1/tasn_prn.c
+++ b/crypto/asn1/tasn_prn.c
@@ -1,5 +1,5 @@
 /* tasn_prn.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/crypto/asn1/tasn_typ.c b/crypto/asn1/tasn_typ.c
index 6f17f1b..6252213 100644
--- a/crypto/asn1/tasn_typ.c
+++ b/crypto/asn1/tasn_typ.c
@@ -1,5 +1,5 @@
 /* tasn_typ.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/crypto/asn1/tasn_utl.c b/crypto/asn1/tasn_utl.c
index 34d520b..ca9ec7a 100644
--- a/crypto/asn1/tasn_utl.c
+++ b/crypto/asn1/tasn_utl.c
@@ -1,5 +1,5 @@
 /* tasn_utl.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/crypto/asn1/x_algor.c b/crypto/asn1/x_algor.c
index 33533ab..99e5342 100644
--- a/crypto/asn1/x_algor.c
+++ b/crypto/asn1/x_algor.c
@@ -1,5 +1,5 @@
 /* x_algor.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/crypto/asn1/x_bignum.c b/crypto/asn1/x_bignum.c
index 869c05d..9cf3204 100644
--- a/crypto/asn1/x_bignum.c
+++ b/crypto/asn1/x_bignum.c
@@ -1,5 +1,5 @@
 /* x_bignum.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/crypto/asn1/x_exten.c b/crypto/asn1/x_exten.c
index 1732e66..3a21239 100644
--- a/crypto/asn1/x_exten.c
+++ b/crypto/asn1/x_exten.c
@@ -1,5 +1,5 @@
 /* x_exten.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/crypto/asn1/x_long.c b/crypto/asn1/x_long.c
index 0db233c..bf35457 100644
--- a/crypto/asn1/x_long.c
+++ b/crypto/asn1/x_long.c
@@ -1,5 +1,5 @@
 /* x_long.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/crypto/asn1/x_nx509.c b/crypto/asn1/x_nx509.c
new file mode 100644
index 0000000..fbd9a22
--- /dev/null
+++ b/crypto/asn1/x_nx509.c
@@ -0,0 +1,72 @@
+/* x_nx509.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stddef.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+
+/* Old netscape certificate wrapper format */
+
+ASN1_SEQUENCE(NETSCAPE_X509) = {
+	ASN1_SIMPLE(NETSCAPE_X509, header, ASN1_OCTET_STRING),
+	ASN1_OPT(NETSCAPE_X509, cert, X509)
+} ASN1_SEQUENCE_END(NETSCAPE_X509)
+
+IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_X509)
+
diff --git a/crypto/asn1/x_x509a.c b/crypto/asn1/x_x509a.c
index 13db5fd..b603f82 100644
--- a/crypto/asn1/x_x509a.c
+++ b/crypto/asn1/x_x509a.c
@@ -1,5 +1,5 @@
 /* a_x509a.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/bio/Makefile b/crypto/bio/Makefile
index 1ef6c2f..1cd76ce 100644
--- a/crypto/bio/Makefile
+++ b/crypto/bio/Makefile
@@ -45,7 +45,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
diff --git a/crypto/bio/bss_bio.c b/crypto/bio/bss_bio.c
index 0f9f095..76bd48e 100644
--- a/crypto/bio/bss_bio.c
+++ b/crypto/bio/bss_bio.c
@@ -919,6 +919,6 @@
 
 	ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf);
 	if (ret > 0)
-		bio->num_read += ret;
+		bio->num_write += ret;
 	return ret;
 	}
diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c
index ea2c3ff..c3da6dc 100644
--- a/crypto/bio/bss_dgram.c
+++ b/crypto/bio/bss_dgram.c
@@ -82,7 +82,7 @@
 static int dgram_free(BIO *data);
 static int dgram_clear(BIO *bio);
 
-int BIO_dgram_should_retry(int s);
+static int BIO_dgram_should_retry(int s);
 
 static BIO_METHOD methods_dgramp=
 	{
@@ -345,30 +345,90 @@
 
         memcpy(&(data->peer), to, sizeof(struct sockaddr));
         break;
+#if defined(SO_RCVTIMEO)
 	case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
+#ifdef OPENSSL_SYS_WINDOWS
+		{
+		struct timeval *tv = (struct timeval *)ptr;
+		int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000;
+		if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+			(void*)&timeout, sizeof(timeout)) < 0)
+			{ perror("setsockopt"); ret = -1; }
+		}
+#else
 		if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
 			sizeof(struct timeval)) < 0)
 			{ perror("setsockopt");	ret = -1; }
+#endif
 		break;
 	case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
+#ifdef OPENSSL_SYS_WINDOWS
+		{
+		int timeout, sz = sizeof(timeout);
+		struct timeval *tv = (struct timeval *)ptr;
+		if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
+			(void*)&timeout, &sz) < 0)
+			{ perror("getsockopt"); ret = -1; }
+		else
+			{
+			tv->tv_sec = timeout / 1000;
+			tv->tv_usec = (timeout % 1000) * 1000;
+			ret = sizeof(*tv);
+			}
+		}
+#else
 		if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 
 			ptr, (void *)&ret) < 0)
 			{ perror("getsockopt"); ret = -1; }
+#endif
 		break;
+#endif
+#if defined(SO_SNDTIMEO)
 	case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
+#ifdef OPENSSL_SYS_WINDOWS
+		{
+		struct timeval *tv = (struct timeval *)ptr;
+		int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000;
+		if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
+			(void*)&timeout, sizeof(timeout)) < 0)
+			{ perror("setsockopt"); ret = -1; }
+		}
+#else
 		if ( setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
 			sizeof(struct timeval)) < 0)
 			{ perror("setsockopt");	ret = -1; }
+#endif
 		break;
 	case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
+#ifdef OPENSSL_SYS_WINDOWS
+		{
+		int timeout, sz = sizeof(timeout);
+		struct timeval *tv = (struct timeval *)ptr;
+		if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
+			(void*)&timeout, &sz) < 0)
+			{ perror("getsockopt"); ret = -1; }
+		else
+			{
+			tv->tv_sec = timeout / 1000;
+			tv->tv_usec = (timeout % 1000) * 1000;
+			ret = sizeof(*tv);
+			}
+		}
+#else
 		if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, 
 			ptr, (void *)&ret) < 0)
 			{ perror("getsockopt"); ret = -1; }
+#endif
 		break;
+#endif
 	case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
 		/* fall-through */
 	case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
+#ifdef OPENSSL_SYS_WINDOWS
+		if ( data->_errno == WSAETIMEDOUT)
+#else
 		if ( data->_errno == EAGAIN)
+#endif
 			{
 			ret = 1;
 			data->_errno = 0;
@@ -403,7 +463,7 @@
 	return(ret);
 	}
 
-int BIO_dgram_should_retry(int i)
+static int BIO_dgram_should_retry(int i)
 	{
 	int err;
 
diff --git a/crypto/bio/bss_file.c b/crypto/bio/bss_file.c
index 4df9927..9ad46fa 100644
--- a/crypto/bio/bss_file.c
+++ b/crypto/bio/bss_file.c
@@ -279,7 +279,7 @@
 #endif
 		{
 #if defined(OPENSSL_SYS_WINDOWS)
-		int fd = fileno((FILE*)ptr);
+		int fd = _fileno((FILE*)ptr);
 		if (num & BIO_FP_TEXT)
 			_setmode(fd,_O_TEXT);
 		else
diff --git a/crypto/bio/bss_mem.c b/crypto/bio/bss_mem.c
index a4edb71..e7ab9cb 100644
--- a/crypto/bio/bss_mem.c
+++ b/crypto/bio/bss_mem.c
@@ -284,6 +284,7 @@
 
 	BIO_clear_retry_flags(bp);
 	j=bm->length;
+	if ((size-1) < j) j=size-1;
 	if (j <= 0)
 		{
 		*buf='\0';
@@ -292,17 +293,18 @@
 	p=bm->data;
 	for (i=0; i<j; i++)
 		{
-		if (p[i] == '\n') break;
+		if (p[i] == '\n')
+			{
+			i++;
+			break;
+			}
 		}
-	if (i == j)
-		{
-		BIO_set_retry_read(bp);
-		/* return(-1);  change the semantics 0.6.6a */ 
-		}
-	else
-		i++;
-	/* i is the max to copy */
-	if ((size-1) < i) i=size-1;
+
+	/*
+	 * i is now the max num of bytes to copy, either j or up to
+	 * and including the first newline
+	 */ 
+
 	i=mem_read(bp,buf,i);
 	if (i > 0) buf[i]='\0';
 	ret=i;
diff --git a/crypto/bio/bss_sock.c b/crypto/bio/bss_sock.c
index 472dd75..30c3cea 100644
--- a/crypto/bio/bss_sock.c
+++ b/crypto/bio/bss_sock.c
@@ -60,6 +60,9 @@
 #include <errno.h>
 #define USE_SOCKETS
 #include "cryptlib.h"
+
+#ifndef OPENSSL_NO_SOCK
+
 #include <openssl/bio.h>
 
 #ifdef WATT32
@@ -300,3 +303,5 @@
 		}
 	return(0);
 	}
+
+#endif  /* #ifndef OPENSSL_NO_SOCK */
diff --git a/crypto/bn/Makefile b/crypto/bn/Makefile
index e97c751..f5e8f65 100644
--- a/crypto/bn/Makefile
+++ b/crypto/bn/Makefile
@@ -28,13 +28,13 @@
 	bn_print.c bn_rand.c bn_shift.c bn_word.c bn_blind.c \
 	bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_err.c bn_sqr.c bn_asm.c \
 	bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c bn_nist.c \
-	bn_depr.c bn_const.c
+	bn_depr.c bn_x931p.c bn_const.c bn_opt.c
 
 LIBOBJ=	bn_add.o bn_div.o bn_exp.o bn_lib.o bn_ctx.o bn_mul.o bn_mod.o \
 	bn_print.o bn_rand.o bn_shift.o bn_word.o bn_blind.o \
 	bn_kron.o bn_sqrt.o bn_gcd.o bn_prime.o bn_err.o bn_sqr.o $(BN_ASM) \
 	bn_recp.o bn_mont.o bn_mpi.o bn_exp2.o bn_gf2m.o bn_nist.o \
-	bn_depr.o bn_const.o
+	bn_depr.o bn_x931p.o bn_const.o bn_opt.o
 
 SRC= $(LIBSRC)
 
@@ -58,7 +58,7 @@
 	cc -g -I../../include bnbug.c -o bnbug ../../libcrypto.a
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -116,6 +116,7 @@
 aix_ppc32.s: asm/ppc.pl;	$(PERL) asm/ppc.pl $@
 aix_ppc64.s: asm/ppc.pl;	$(PERL) asm/ppc.pl $@
 osx_ppc32.s: asm/ppc.pl;	$(PERL) $< $@
+osx_ppc64.s: asm/ppc.pl;	$(PERL) $< $@
 
 files:
 	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
@@ -291,6 +292,13 @@
 bn_nist.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 bn_nist.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 bn_nist.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_nist.c
+bn_opt.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
+bn_opt.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+bn_opt.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+bn_opt.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+bn_opt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bn_opt.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bn_opt.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_opt.c
 bn_prime.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 bn_prime.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bn_prime.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
@@ -349,3 +357,6 @@
 bn_word.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 bn_word.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 bn_word.o: ../../include/openssl/symhacks.h ../cryptlib.h bn_lcl.h bn_word.c
+bn_x931p.o: ../../include/openssl/bn.h ../../include/openssl/e_os2.h
+bn_x931p.o: ../../include/openssl/opensslconf.h
+bn_x931p.o: ../../include/openssl/ossl_typ.h bn_x931p.c
diff --git a/crypto/bn/asm/alpha-mont.pl b/crypto/bn/asm/alpha-mont.pl
new file mode 100644
index 0000000..7a2cc31
--- /dev/null
+++ b/crypto/bn/asm/alpha-mont.pl
@@ -0,0 +1,317 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# On 21264 RSA sign performance improves by 70/35/20/15 percent for
+# 512/1024/2048/4096 bit key lengths. This is against vendor compiler
+# instructed to '-tune host' code with in-line assembler. Other
+# benchmarks improve by 15-20%. To anchor it to something else, the
+# code provides approximately the same performance per GHz as AMD64.
+# I.e. if you compare 1GHz 21264 and 2GHz Opteron, you'll observe ~2x
+# difference.
+
+# int bn_mul_mont(
+$rp="a0";	# BN_ULONG *rp,
+$ap="a1";	# const BN_ULONG *ap,
+$bp="a2";	# const BN_ULONG *bp,
+$np="a3";	# const BN_ULONG *np,
+$n0="a4";	# const BN_ULONG *n0,
+$num="a5";	# int num);
+
+$lo0="t0";
+$hi0="t1";
+$lo1="t2";
+$hi1="t3";
+$aj="t4";
+$bi="t5";
+$nj="t6";
+$tp="t7";
+$alo="t8";
+$ahi="t9";
+$nlo="t10";
+$nhi="t11";
+$tj="t12";
+$i="s3";
+$j="s4";
+$m1="s5";
+
+$code=<<___;
+#include <asm.h>
+#include <regdef.h>
+
+.text
+
+.set	noat
+.set	noreorder
+
+.globl	bn_mul_mont
+.align	5
+.ent	bn_mul_mont
+bn_mul_mont:
+	lda	sp,-40(sp)
+	stq	ra,0(sp)
+	stq	s3,8(sp)
+	stq	s4,16(sp)
+	stq	s5,24(sp)
+	stq	fp,32(sp)
+	mov	sp,fp
+	.mask	0x0400f000,-40
+	.frame	fp,40,ra
+	.prologue 0
+
+	.align	4
+	.set	reorder
+	sextl	$num,$num
+	mov	0,v0
+	cmplt	$num,4,AT
+	bne	AT,.Lexit
+
+	ldq	$hi0,0($ap)	# ap[0]
+	s8addq	$num,16,AT
+	ldq	$aj,8($ap)
+	subq	sp,AT,sp
+	ldq	$bi,0($bp)	# bp[0]
+	mov	-4096,AT
+	ldq	$n0,0($n0)
+	and	sp,AT,sp
+
+	mulq	$hi0,$bi,$lo0
+	ldq	$hi1,0($np)	# np[0]
+	umulh	$hi0,$bi,$hi0
+	ldq	$nj,8($np)
+
+	mulq	$lo0,$n0,$m1
+
+	mulq	$hi1,$m1,$lo1
+	umulh	$hi1,$m1,$hi1
+
+	addq	$lo1,$lo0,$lo1
+	cmpult	$lo1,$lo0,AT
+	addq	$hi1,AT,$hi1
+
+	mulq	$aj,$bi,$alo
+	mov	2,$j
+	umulh	$aj,$bi,$ahi
+	mov	sp,$tp
+
+	mulq	$nj,$m1,$nlo
+	s8addq	$j,$ap,$aj
+	umulh	$nj,$m1,$nhi
+	s8addq	$j,$np,$nj
+.align	4
+.L1st:
+	.set	noreorder
+	ldq	$aj,($aj)
+	addl	$j,1,$j
+	ldq	$nj,($nj)
+	lda	$tp,8($tp)
+
+	addq	$alo,$hi0,$lo0
+	mulq	$aj,$bi,$alo
+	cmpult	$lo0,$hi0,AT
+	addq	$nlo,$hi1,$lo1
+
+	mulq	$nj,$m1,$nlo
+	addq	$ahi,AT,$hi0
+	cmpult	$lo1,$hi1,v0
+	cmplt	$j,$num,$tj
+
+	umulh	$aj,$bi,$ahi
+	addq	$nhi,v0,$hi1
+	addq	$lo1,$lo0,$lo1
+	s8addq	$j,$ap,$aj
+
+	umulh	$nj,$m1,$nhi
+	cmpult	$lo1,$lo0,v0
+	addq	$hi1,v0,$hi1
+	s8addq	$j,$np,$nj
+
+	stq	$lo1,-8($tp)
+	nop
+	unop
+	bne	$tj,.L1st
+	.set	reorder
+
+	addq	$alo,$hi0,$lo0
+	addq	$nlo,$hi1,$lo1
+	cmpult	$lo0,$hi0,AT
+	cmpult	$lo1,$hi1,v0
+	addq	$ahi,AT,$hi0
+	addq	$nhi,v0,$hi1
+
+	addq	$lo1,$lo0,$lo1
+	cmpult	$lo1,$lo0,v0
+	addq	$hi1,v0,$hi1
+
+	stq	$lo1,0($tp)
+
+	addq	$hi1,$hi0,$hi1
+	cmpult	$hi1,$hi0,AT
+	stq	$hi1,8($tp)
+	stq	AT,16($tp)
+
+	mov	1,$i
+.align	4
+.Louter:
+	s8addq	$i,$bp,$bi
+	ldq	$hi0,($ap)
+	ldq	$aj,8($ap)
+	ldq	$bi,($bi)
+	ldq	$hi1,($np)
+	ldq	$nj,8($np)
+	ldq	$tj,(sp)
+
+	mulq	$hi0,$bi,$lo0
+	umulh	$hi0,$bi,$hi0
+
+	addq	$lo0,$tj,$lo0
+	cmpult	$lo0,$tj,AT
+	addq	$hi0,AT,$hi0
+
+	mulq	$lo0,$n0,$m1
+
+	mulq	$hi1,$m1,$lo1
+	umulh	$hi1,$m1,$hi1
+
+	addq	$lo1,$lo0,$lo1
+	cmpult	$lo1,$lo0,AT
+	mov	2,$j
+	addq	$hi1,AT,$hi1
+
+	mulq	$aj,$bi,$alo
+	mov	sp,$tp
+	umulh	$aj,$bi,$ahi
+
+	mulq	$nj,$m1,$nlo
+	s8addq	$j,$ap,$aj
+	umulh	$nj,$m1,$nhi
+.align	4
+.Linner:
+	.set	noreorder
+	ldq	$tj,8($tp)	#L0
+	nop			#U1
+	ldq	$aj,($aj)	#L1
+	s8addq	$j,$np,$nj	#U0
+
+	ldq	$nj,($nj)	#L0
+	nop			#U1
+	addq	$alo,$hi0,$lo0	#L1
+	lda	$tp,8($tp)
+
+	mulq	$aj,$bi,$alo	#U1
+	cmpult	$lo0,$hi0,AT	#L0
+	addq	$nlo,$hi1,$lo1	#L1
+	addl	$j,1,$j
+
+	mulq	$nj,$m1,$nlo	#U1
+	addq	$ahi,AT,$hi0	#L0
+	addq	$lo0,$tj,$lo0	#L1
+	cmpult	$lo1,$hi1,v0	#U0
+
+	umulh	$aj,$bi,$ahi	#U1
+	cmpult	$lo0,$tj,AT	#L0
+	addq	$lo1,$lo0,$lo1	#L1
+	addq	$nhi,v0,$hi1	#U0
+
+	umulh	$nj,$m1,$nhi	#U1
+	s8addq	$j,$ap,$aj	#L0
+	cmpult	$lo1,$lo0,v0	#L1
+	cmplt	$j,$num,$tj	#U0	# borrow $tj
+
+	addq	$hi0,AT,$hi0	#L0
+	addq	$hi1,v0,$hi1	#U1
+	stq	$lo1,-8($tp)	#L1
+	bne	$tj,.Linner	#U0
+	.set	reorder
+
+	ldq	$tj,8($tp)
+	addq	$alo,$hi0,$lo0
+	addq	$nlo,$hi1,$lo1
+	cmpult	$lo0,$hi0,AT
+	cmpult	$lo1,$hi1,v0
+	addq	$ahi,AT,$hi0
+	addq	$nhi,v0,$hi1
+
+	addq	$lo0,$tj,$lo0
+	cmpult	$lo0,$tj,AT
+	addq	$hi0,AT,$hi0
+
+	ldq	$tj,16($tp)
+	addq	$lo1,$lo0,$j
+	cmpult	$j,$lo0,v0
+	addq	$hi1,v0,$hi1
+
+	addq	$hi1,$hi0,$lo1
+	stq	$j,($tp)
+	cmpult	$lo1,$hi0,$hi1
+	addq	$lo1,$tj,$lo1
+	cmpult	$lo1,$tj,AT
+	addl	$i,1,$i
+	addq	$hi1,AT,$hi1
+	stq	$lo1,8($tp)
+	cmplt	$i,$num,$tj	# borrow $tj
+	stq	$hi1,16($tp)
+	bne	$tj,.Louter
+
+	s8addq	$num,sp,$tj	# &tp[num]
+	mov	$rp,$bp		# put rp aside
+	mov	sp,$tp
+	mov	sp,$ap
+	mov	0,$hi0		# clear borrow bit
+
+.align	4
+.Lsub:	ldq	$lo0,($tp)
+	ldq	$lo1,($np)
+	lda	$tp,8($tp)
+	lda	$np,8($np)
+	subq	$lo0,$lo1,$lo1	# tp[i]-np[i]
+	cmpult	$lo0,$lo1,AT
+	subq	$lo1,$hi0,$lo0
+	cmpult	$lo1,$lo0,$hi0
+	or	$hi0,AT,$hi0
+	stq	$lo0,($rp)
+	cmpult	$tp,$tj,v0
+	lda	$rp,8($rp)
+	bne	v0,.Lsub
+
+	subq	$hi1,$hi0,$hi0	# handle upmost overflow bit
+	mov	sp,$tp
+	mov	$bp,$rp		# restore rp
+
+	and	sp,$hi0,$ap
+	bic	$bp,$hi0,$bp
+	bis	$bp,$ap,$ap	# ap=borrow?tp:rp
+
+.align	4
+.Lcopy:	ldq	$aj,($ap)	# copy or in-place refresh
+	lda	$tp,8($tp)
+	lda	$rp,8($rp)
+	lda	$ap,8($ap)
+	stq	zero,-8($tp)	# zap tp
+	cmpult	$tp,$tj,AT
+	stq	$aj,-8($rp)
+	bne	AT,.Lcopy
+	mov	1,v0
+
+.Lexit:
+	.set	noreorder
+	mov	fp,sp
+	/*ldq	ra,0(sp)*/
+	ldq	s3,8(sp)
+	ldq	s4,16(sp)
+	ldq	s5,24(sp)
+	ldq	fp,32(sp)
+	lda	sp,40(sp)
+	ret	(ra)
+.end	bn_mul_mont
+.rdata
+.asciiz	"Montgomery Multiplication for Alpha, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+print $code;
+close STDOUT;
diff --git a/crypto/bn/asm/armv4-mont.pl b/crypto/bn/asm/armv4-mont.pl
new file mode 100644
index 0000000..05d5dc1
--- /dev/null
+++ b/crypto/bn/asm/armv4-mont.pl
@@ -0,0 +1,200 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# January 2007.
+
+# Montgomery multiplication for ARMv4.
+#
+# Performance improvement naturally varies among CPU implementations
+# and compilers. The code was observed to provide +65-35% improvement
+# [depending on key length, less for longer keys] on ARM920T, and
+# +115-80% on Intel IXP425. This is compared to pre-bn_mul_mont code
+# base and compiler generated code with in-lined umull and even umlal
+# instructions. The latter means that this code didn't really have an 
+# "advantage" of utilizing some "secret" instruction.
+#
+# The code is interoperable with Thumb ISA and is rather compact, less
+# than 1/2KB. Windows CE port would be trivial, as it's exclusively
+# about decorations, ABI and instruction syntax are identical.
+
+$num="r0";	# starts as num argument, but holds &tp[num-1]
+$ap="r1";
+$bp="r2"; $bi="r2"; $rp="r2";
+$np="r3";
+$tp="r4";
+$aj="r5";
+$nj="r6";
+$tj="r7";
+$n0="r8";
+###########	# r9 is reserved by ELF as platform specific, e.g. TLS pointer
+$alo="r10";	# sl, gcc uses it to keep @GOT
+$ahi="r11";	# fp
+$nlo="r12";	# ip
+###########	# r13 is stack pointer
+$nhi="r14";	# lr
+###########	# r15 is program counter
+
+#### argument block layout relative to &tp[num-1], a.k.a. $num
+$_rp="$num,#12*4";
+# ap permanently resides in r1
+$_bp="$num,#13*4";
+# np permanently resides in r3
+$_n0="$num,#14*4";
+$_num="$num,#15*4";	$_bpend=$_num;
+
+$code=<<___;
+.text
+
+.global	bn_mul_mont
+.type	bn_mul_mont,%function
+
+.align	2
+bn_mul_mont:
+	stmdb	sp!,{r0,r2}		@ sp points at argument block
+	ldr	$num,[sp,#3*4]		@ load num
+	cmp	$num,#2
+	movlt	r0,#0
+	addlt	sp,sp,#2*4
+	blt	.Labrt
+
+	stmdb	sp!,{r4-r12,lr}		@ save 10 registers
+
+	mov	$num,$num,lsl#2		@ rescale $num for byte count
+	sub	sp,sp,$num		@ alloca(4*num)
+	sub	sp,sp,#4		@ +extra dword
+	sub	$num,$num,#4		@ "num=num-1"
+	add	$tp,$bp,$num		@ &bp[num-1]
+
+	add	$num,sp,$num		@ $num to point at &tp[num-1]
+	ldr	$n0,[$_n0]		@ &n0
+	ldr	$bi,[$bp]		@ bp[0]
+	ldr	$aj,[$ap],#4		@ ap[0],ap++
+	ldr	$nj,[$np],#4		@ np[0],np++
+	ldr	$n0,[$n0]		@ *n0
+	str	$tp,[$_bpend]		@ save &bp[num]
+
+	umull	$alo,$ahi,$aj,$bi	@ ap[0]*bp[0]
+	str	$n0,[$_n0]		@ save n0 value
+	mul	$n0,$alo,$n0		@ "tp[0]"*n0
+	mov	$nlo,#0
+	umlal	$alo,$nlo,$nj,$n0	@ np[0]*n0+"t[0]"
+	mov	$tp,sp
+
+.L1st:
+	ldr	$aj,[$ap],#4		@ ap[j],ap++
+	mov	$alo,$ahi
+	mov	$ahi,#0
+	umlal	$alo,$ahi,$aj,$bi	@ ap[j]*bp[0]
+	ldr	$nj,[$np],#4		@ np[j],np++
+	mov	$nhi,#0
+	umlal	$nlo,$nhi,$nj,$n0	@ np[j]*n0
+	adds	$nlo,$nlo,$alo
+	str	$nlo,[$tp],#4		@ tp[j-1]=,tp++
+	adc	$nlo,$nhi,#0
+	cmp	$tp,$num
+	bne	.L1st
+
+	adds	$nlo,$nlo,$ahi
+	mov	$nhi,#0
+	adc	$nhi,$nhi,#0
+	ldr	$tp,[$_bp]		@ restore bp
+	str	$nlo,[$num]		@ tp[num-1]=
+	ldr	$n0,[$_n0]		@ restore n0
+	str	$nhi,[$num,#4]		@ tp[num]=
+
+.Louter:
+	sub	$tj,$num,sp		@ "original" $num-1 value
+	sub	$ap,$ap,$tj		@ "rewind" ap to &ap[1]
+	sub	$np,$np,$tj		@ "rewind" np to &np[1]
+	ldr	$bi,[$tp,#4]!		@ *(++bp)
+	ldr	$aj,[$ap,#-4]		@ ap[0]
+	ldr	$nj,[$np,#-4]		@ np[0]
+	ldr	$alo,[sp]		@ tp[0]
+	ldr	$tj,[sp,#4]		@ tp[1]
+
+	mov	$ahi,#0
+	umlal	$alo,$ahi,$aj,$bi	@ ap[0]*bp[i]+tp[0]
+	str	$tp,[$_bp]		@ save bp
+	mul	$n0,$alo,$n0
+	mov	$nlo,#0
+	umlal	$alo,$nlo,$nj,$n0	@ np[0]*n0+"tp[0]"
+	mov	$tp,sp
+
+.Linner:
+	ldr	$aj,[$ap],#4		@ ap[j],ap++
+	adds	$alo,$ahi,$tj		@ +=tp[j]
+	mov	$ahi,#0
+	umlal	$alo,$ahi,$aj,$bi	@ ap[j]*bp[i]
+	ldr	$nj,[$np],#4		@ np[j],np++
+	mov	$nhi,#0
+	umlal	$nlo,$nhi,$nj,$n0	@ np[j]*n0
+	ldr	$tj,[$tp,#8]		@ tp[j+1]
+	adc	$ahi,$ahi,#0
+	adds	$nlo,$nlo,$alo
+	str	$nlo,[$tp],#4		@ tp[j-1]=,tp++
+	adc	$nlo,$nhi,#0
+	cmp	$tp,$num
+	bne	.Linner
+
+	adds	$nlo,$nlo,$ahi
+	mov	$nhi,#0
+	adc	$nhi,$nhi,#0
+	adds	$nlo,$nlo,$tj
+	adc	$nhi,$nhi,#0
+	ldr	$tp,[$_bp]		@ restore bp
+	ldr	$tj,[$_bpend]		@ restore &bp[num]
+	str	$nlo,[$num]		@ tp[num-1]=
+	ldr	$n0,[$_n0]		@ restore n0
+	str	$nhi,[$num,#4]		@ tp[num]=
+
+	cmp	$tp,$tj
+	bne	.Louter
+
+	ldr	$rp,[$_rp]		@ pull rp
+	add	$num,$num,#4		@ $num to point at &tp[num]
+	sub	$aj,$num,sp		@ "original" num value
+	mov	$tp,sp			@ "rewind" $tp
+	mov	$ap,$tp			@ "borrow" $ap
+	sub	$np,$np,$aj		@ "rewind" $np to &np[0]
+
+	subs	$tj,$tj,$tj		@ "clear" carry flag
+.Lsub:	ldr	$tj,[$tp],#4
+	ldr	$nj,[$np],#4
+	sbcs	$tj,$tj,$nj		@ tp[j]-np[j]
+	str	$tj,[$rp],#4		@ rp[j]=
+	teq	$tp,$num		@ preserve carry
+	bne	.Lsub
+	sbcs	$nhi,$nhi,#0		@ upmost carry
+	mov	$tp,sp			@ "rewind" $tp
+	sub	$rp,$rp,$aj		@ "rewind" $rp
+
+	and	$ap,$tp,$nhi
+	bic	$np,$rp,$nhi
+	orr	$ap,$ap,$np		@ ap=borrow?tp:rp
+
+.Lcopy:	ldr	$tj,[$ap],#4		@ copy or in-place refresh
+	str	sp,[$tp],#4		@ zap tp
+	str	$tj,[$rp],#4
+	cmp	$tp,$num
+	bne	.Lcopy
+
+	add	sp,$num,#4		@ skip over tp[num+1]
+	ldmia	sp!,{r4-r12,lr}		@ restore registers
+	add	sp,sp,#2*4		@ skip over {r0,r2}
+	mov	r0,#1
+.Labrt:	tst	lr,#1
+	moveq	pc,lr			@ be binary compatible with V4, yet
+	bx	lr			@ interoperable with Thumb ISA:-)
+.size	bn_mul_mont,.-bn_mul_mont
+.asciz	"Montgomery multiplication for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
+print $code;
+close STDOUT;
diff --git a/crypto/bn/asm/mips3-mont.pl b/crypto/bn/asm/mips3-mont.pl
new file mode 100644
index 0000000..8f9156e
--- /dev/null
+++ b/crypto/bn/asm/mips3-mont.pl
@@ -0,0 +1,327 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# This module doesn't present direct interest for OpenSSL, because it
+# doesn't provide better performance for longer keys. While 512-bit
+# RSA private key operations are 40% faster, 1024-bit ones are hardly
+# faster at all, while longer key operations are slower by up to 20%.
+# It might be of interest to embedded system developers though, as
+# it's smaller than 1KB, yet offers ~3x improvement over compiler
+# generated code.
+#
+# The module targets N32 and N64 MIPS ABIs and currently is a bit
+# IRIX-centric, i.e. is likely to require adaptation for other OSes.
+
+# int bn_mul_mont(
+$rp="a0";	# BN_ULONG *rp,
+$ap="a1";	# const BN_ULONG *ap,
+$bp="a2";	# const BN_ULONG *bp,
+$np="a3";	# const BN_ULONG *np,
+$n0="a4";	# const BN_ULONG *n0,
+$num="a5";	# int num);
+
+$lo0="a6";
+$hi0="a7";
+$lo1="v0";
+$hi1="v1";
+$aj="t0";
+$bi="t1";
+$nj="t2";
+$tp="t3";
+$alo="s0";
+$ahi="s1";
+$nlo="s2";
+$nhi="s3";
+$tj="s4";
+$i="s5";
+$j="s6";
+$fp="t8";
+$m1="t9";
+
+$FRAME=8*(2+8);
+
+$code=<<___;
+#include <asm.h>
+#include <regdef.h>
+
+.text
+
+.set	noat
+.set	reorder
+
+.align	5
+.globl	bn_mul_mont
+.ent	bn_mul_mont
+bn_mul_mont:
+	.set	noreorder
+	PTR_SUB	sp,64
+	move	$fp,sp
+	.frame	$fp,64,ra
+	slt	AT,$num,4
+	li	v0,0
+	beqzl	AT,.Lproceed
+	nop
+	jr	ra
+	PTR_ADD	sp,$fp,64
+	.set	reorder
+.align	5
+.Lproceed:
+	ld	$n0,0($n0)
+	ld	$bi,0($bp)	# bp[0]
+	ld	$aj,0($ap)	# ap[0]
+	ld	$nj,0($np)	# np[0]
+	PTR_SUB	sp,16		# place for two extra words
+	sll	$num,3
+	li	AT,-4096
+	PTR_SUB	sp,$num
+	and	sp,AT
+
+	sd	s0,0($fp)
+	sd	s1,8($fp)
+	sd	s2,16($fp)
+	sd	s3,24($fp)
+	sd	s4,32($fp)
+	sd	s5,40($fp)
+	sd	s6,48($fp)
+	sd	s7,56($fp)
+
+	dmultu	$aj,$bi
+	ld	$alo,8($ap)
+	ld	$nlo,8($np)
+	mflo	$lo0
+	mfhi	$hi0
+	dmultu	$lo0,$n0
+	mflo	$m1
+
+	dmultu	$alo,$bi
+	mflo	$alo
+	mfhi	$ahi
+
+	dmultu	$nj,$m1
+	mflo	$lo1
+	mfhi	$hi1
+	dmultu	$nlo,$m1
+	daddu	$lo1,$lo0
+	sltu	AT,$lo1,$lo0
+	daddu	$hi1,AT
+	mflo	$nlo
+	mfhi	$nhi
+
+	move	$tp,sp
+	li	$j,16
+.align	4
+.L1st:
+	.set	noreorder
+	PTR_ADD	$aj,$ap,$j
+	ld	$aj,($aj)
+	PTR_ADD	$nj,$np,$j
+	ld	$nj,($nj)
+
+	dmultu	$aj,$bi
+	daddu	$lo0,$alo,$hi0
+	daddu	$lo1,$nlo,$hi1
+	sltu	AT,$lo0,$hi0
+	sltu	s7,$lo1,$hi1
+	daddu	$hi0,$ahi,AT
+	daddu	$hi1,$nhi,s7
+	mflo	$alo
+	mfhi	$ahi
+
+	daddu	$lo1,$lo0
+	sltu	AT,$lo1,$lo0
+	dmultu	$nj,$m1
+	daddu	$hi1,AT
+	addu	$j,8
+	sd	$lo1,($tp)
+	sltu	s7,$j,$num
+	mflo	$nlo
+	mfhi	$nhi
+
+	bnez	s7,.L1st
+	PTR_ADD	$tp,8
+	.set	reorder
+
+	daddu	$lo0,$alo,$hi0
+	sltu	AT,$lo0,$hi0
+	daddu	$hi0,$ahi,AT
+
+	daddu	$lo1,$nlo,$hi1
+	sltu	s7,$lo1,$hi1
+	daddu	$hi1,$nhi,s7
+	daddu	$lo1,$lo0
+	sltu	AT,$lo1,$lo0
+	daddu	$hi1,AT
+
+	sd	$lo1,($tp)
+
+	daddu	$hi1,$hi0
+	sltu	AT,$hi1,$hi0
+	sd	$hi1,8($tp)
+	sd	AT,16($tp)
+
+	li	$i,8
+.align	4
+.Louter:
+	PTR_ADD	$bi,$bp,$i
+	ld	$bi,($bi)
+	ld	$aj,($ap)
+	ld	$alo,8($ap)
+	ld	$tj,(sp)
+
+	dmultu	$aj,$bi
+	ld	$nj,($np)
+	ld	$nlo,8($np)
+	mflo	$lo0
+	mfhi	$hi0
+	daddu	$lo0,$tj
+	dmultu	$lo0,$n0
+	sltu	AT,$lo0,$tj
+	daddu	$hi0,AT
+	mflo	$m1
+
+	dmultu	$alo,$bi
+	mflo	$alo
+	mfhi	$ahi
+
+	dmultu	$nj,$m1
+	mflo	$lo1
+	mfhi	$hi1
+
+	dmultu	$nlo,$m1
+	daddu	$lo1,$lo0
+	sltu	AT,$lo1,$lo0
+	daddu	$hi1,AT
+	mflo	$nlo
+	mfhi	$nhi
+
+	move	$tp,sp
+	li	$j,16
+	ld	$tj,8($tp)
+.align	4
+.Linner:
+	.set	noreorder
+	PTR_ADD	$aj,$ap,$j
+	ld	$aj,($aj)
+	PTR_ADD	$nj,$np,$j
+	ld	$nj,($nj)
+
+	dmultu	$aj,$bi
+	daddu	$lo0,$alo,$hi0
+	daddu	$lo1,$nlo,$hi1
+	sltu	AT,$lo0,$hi0
+	sltu	s7,$lo1,$hi1
+	daddu	$hi0,$ahi,AT
+	daddu	$hi1,$nhi,s7
+	mflo	$alo
+	mfhi	$ahi
+
+	daddu	$lo0,$tj
+	addu	$j,8
+	dmultu	$nj,$m1
+	sltu	AT,$lo0,$tj
+	daddu	$lo1,$lo0
+	daddu	$hi0,AT
+	sltu	s7,$lo1,$lo0
+	ld	$tj,16($tp)
+	daddu	$hi1,s7
+	sltu	AT,$j,$num
+	mflo	$nlo
+	mfhi	$nhi
+	sd	$lo1,($tp)
+	bnez	AT,.Linner
+	PTR_ADD	$tp,8
+	.set	reorder
+
+	daddu	$lo0,$alo,$hi0
+	sltu	AT,$lo0,$hi0
+	daddu	$hi0,$ahi,AT
+	daddu	$lo0,$tj
+	sltu	s7,$lo0,$tj
+	daddu	$hi0,s7
+
+	ld	$tj,16($tp)
+	daddu	$lo1,$nlo,$hi1
+	sltu	AT,$lo1,$hi1
+	daddu	$hi1,$nhi,AT
+	daddu	$lo1,$lo0
+	sltu	s7,$lo1,$lo0
+	daddu	$hi1,s7
+	sd	$lo1,($tp)
+
+	daddu	$lo1,$hi1,$hi0
+	sltu	$hi1,$lo1,$hi0
+	daddu	$lo1,$tj
+	sltu	AT,$lo1,$tj
+	daddu	$hi1,AT
+	sd	$lo1,8($tp)
+	sd	$hi1,16($tp)
+
+	addu	$i,8
+	sltu	s7,$i,$num
+	bnez	s7,.Louter
+
+	.set	noreorder
+	PTR_ADD	$tj,sp,$num	# &tp[num]
+	move	$tp,sp
+	move	$ap,sp
+	li	$hi0,0		# clear borrow bit
+
+.align	4
+.Lsub:	ld	$lo0,($tp)
+	ld	$lo1,($np)
+	PTR_ADD	$tp,8
+	PTR_ADD	$np,8
+	dsubu	$lo1,$lo0,$lo1	# tp[i]-np[i]
+	sgtu	AT,$lo1,$lo0
+	dsubu	$lo0,$lo1,$hi0
+	sgtu	$hi0,$lo0,$lo1
+	sd	$lo0,($rp)
+	or	$hi0,AT
+	sltu	AT,$tp,$tj
+	bnez	AT,.Lsub
+	PTR_ADD	$rp,8
+
+	dsubu	$hi0,$hi1,$hi0	# handle upmost overflow bit
+	move	$tp,sp
+	PTR_SUB	$rp,$num	# restore rp
+	not	$hi1,$hi0
+
+	and	$ap,$hi0,sp
+	and	$bp,$hi1,$rp
+	or	$ap,$ap,$bp	# ap=borrow?tp:rp
+
+.align	4
+.Lcopy:	ld	$aj,($ap)
+	PTR_ADD	$ap,8
+	PTR_ADD	$tp,8
+	sd	zero,-8($tp)
+	sltu	AT,$tp,$tj
+	sd	$aj,($rp)
+	bnez	AT,.Lcopy
+	PTR_ADD	$rp,8
+
+	ld	s0,0($fp)
+	ld	s1,8($fp)
+	ld	s2,16($fp)
+	ld	s3,24($fp)
+	ld	s4,32($fp)
+	ld	s5,40($fp)
+	ld	s6,48($fp)
+	ld	s7,56($fp)
+	li	v0,1
+	jr	ra
+	PTR_ADD	sp,$fp,64
+	.set	reorder
+END(bn_mul_mont)
+.rdata
+.asciiz	"Montgomery Multiplication for MIPS III/IV, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+print $code;
+close STDOUT;
diff --git a/crypto/bn/asm/ppc-mont.pl b/crypto/bn/asm/ppc-mont.pl
new file mode 100644
index 0000000..7849eae
--- /dev/null
+++ b/crypto/bn/asm/ppc-mont.pl
@@ -0,0 +1,323 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# April 2006
+
+# "Teaser" Montgomery multiplication module for PowerPC. It's possible
+# to gain a bit more by modulo-scheduling outer loop, then dedicated
+# squaring procedure should give further 20% and code can be adapted
+# for 32-bit application running on 64-bit CPU. As for the latter.
+# It won't be able to achieve "native" 64-bit performance, because in
+# 32-bit application context every addc instruction will have to be
+# expanded as addc, twice right shift by 32 and finally adde, etc.
+# So far RSA *sign* performance improvement over pre-bn_mul_mont asm
+# for 64-bit application running on PPC970/G5 is:
+#
+# 512-bit	+65%	
+# 1024-bit	+35%
+# 2048-bit	+18%
+# 4096-bit	+4%
+
+$flavour = shift;
+
+if ($flavour =~ /32/) {
+	$BITS=	32;
+	$BNSZ=	$BITS/8;
+	$SIZE_T=4;
+	$RZONE=	224;
+	$FRAME=	$SIZE_T*16;
+
+	$LD=	"lwz";		# load
+	$LDU=	"lwzu";		# load and update
+	$LDX=	"lwzx";		# load indexed
+	$ST=	"stw";		# store
+	$STU=	"stwu";		# store and update
+	$STX=	"stwx";		# store indexed
+	$STUX=	"stwux";	# store indexed and update
+	$UMULL=	"mullw";	# unsigned multiply low
+	$UMULH=	"mulhwu";	# unsigned multiply high
+	$UCMP=	"cmplw";	# unsigned compare
+	$SHRI=	"srwi";		# unsigned shift right by immediate	
+	$PUSH=	$ST;
+	$POP=	$LD;
+} elsif ($flavour =~ /64/) {
+	$BITS=	64;
+	$BNSZ=	$BITS/8;
+	$SIZE_T=8;
+	$RZONE=	288;
+	$FRAME=	$SIZE_T*16;
+
+	# same as above, but 64-bit mnemonics...
+	$LD=	"ld";		# load
+	$LDU=	"ldu";		# load and update
+	$LDX=	"ldx";		# load indexed
+	$ST=	"std";		# store
+	$STU=	"stdu";		# store and update
+	$STX=	"stdx";		# store indexed
+	$STUX=	"stdux";	# store indexed and update
+	$UMULL=	"mulld";	# unsigned multiply low
+	$UMULH=	"mulhdu";	# unsigned multiply high
+	$UCMP=	"cmpld";	# unsigned compare
+	$SHRI=	"srdi";		# unsigned shift right by immediate	
+	$PUSH=	$ST;
+	$POP=	$LD;
+} else { die "nonsense $flavour"; }
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
+die "can't locate ppc-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
+
+$sp="r1";
+$toc="r2";
+$rp="r3";	$ovf="r3";
+$ap="r4";
+$bp="r5";
+$np="r6";
+$n0="r7";
+$num="r8";
+$rp="r9";	# $rp is reassigned
+$aj="r10";
+$nj="r11";
+$tj="r12";
+# non-volatile registers
+$i="r14";
+$j="r15";
+$tp="r16";
+$m0="r17";
+$m1="r18";
+$lo0="r19";
+$hi0="r20";
+$lo1="r21";
+$hi1="r22";
+$alo="r23";
+$ahi="r24";
+$nlo="r25";
+#
+$nhi="r0";
+
+$code=<<___;
+.machine "any"
+.text
+
+.globl	.bn_mul_mont
+.align	4
+.bn_mul_mont:
+	cmpwi	$num,4
+	mr	$rp,r3		; $rp is reassigned
+	li	r3,0
+	bltlr
+
+	slwi	$num,$num,`log($BNSZ)/log(2)`
+	li	$tj,-4096
+	addi	$ovf,$num,`$FRAME+$RZONE`
+	subf	$ovf,$ovf,$sp	; $sp-$ovf
+	and	$ovf,$ovf,$tj	; minimize TLB usage
+	subf	$ovf,$sp,$ovf	; $ovf-$sp
+	srwi	$num,$num,`log($BNSZ)/log(2)`
+	$STUX	$sp,$sp,$ovf
+
+	$PUSH	r14,`4*$SIZE_T`($sp)
+	$PUSH	r15,`5*$SIZE_T`($sp)
+	$PUSH	r16,`6*$SIZE_T`($sp)
+	$PUSH	r17,`7*$SIZE_T`($sp)
+	$PUSH	r18,`8*$SIZE_T`($sp)
+	$PUSH	r19,`9*$SIZE_T`($sp)
+	$PUSH	r20,`10*$SIZE_T`($sp)
+	$PUSH	r21,`11*$SIZE_T`($sp)
+	$PUSH	r22,`12*$SIZE_T`($sp)
+	$PUSH	r23,`13*$SIZE_T`($sp)
+	$PUSH	r24,`14*$SIZE_T`($sp)
+	$PUSH	r25,`15*$SIZE_T`($sp)
+
+	$LD	$n0,0($n0)	; pull n0[0] value
+	addi	$num,$num,-2	; adjust $num for counter register
+
+	$LD	$m0,0($bp)	; m0=bp[0]
+	$LD	$aj,0($ap)	; ap[0]
+	addi	$tp,$sp,$FRAME
+	$UMULL	$lo0,$aj,$m0	; ap[0]*bp[0]
+	$UMULH	$hi0,$aj,$m0
+
+	$LD	$aj,$BNSZ($ap)	; ap[1]
+	$LD	$nj,0($np)	; np[0]
+
+	$UMULL	$m1,$lo0,$n0	; "tp[0]"*n0
+
+	$UMULL	$alo,$aj,$m0	; ap[1]*bp[0]
+	$UMULH	$ahi,$aj,$m0
+
+	$UMULL	$lo1,$nj,$m1	; np[0]*m1
+	$UMULH	$hi1,$nj,$m1
+	$LD	$nj,$BNSZ($np)	; np[1]
+	addc	$lo1,$lo1,$lo0
+	addze	$hi1,$hi1
+
+	$UMULL	$nlo,$nj,$m1	; np[1]*m1
+	$UMULH	$nhi,$nj,$m1
+
+	mtctr	$num
+	li	$j,`2*$BNSZ`
+.align	4
+L1st:
+	$LDX	$aj,$ap,$j	; ap[j]
+	addc	$lo0,$alo,$hi0
+	$LDX	$nj,$np,$j	; np[j]
+	addze	$hi0,$ahi
+	$UMULL	$alo,$aj,$m0	; ap[j]*bp[0]
+	addc	$lo1,$nlo,$hi1
+	$UMULH	$ahi,$aj,$m0
+	addze	$hi1,$nhi
+	$UMULL	$nlo,$nj,$m1	; np[j]*m1
+	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[0]
+	$UMULH	$nhi,$nj,$m1
+	addze	$hi1,$hi1
+	$ST	$lo1,0($tp)	; tp[j-1]
+
+	addi	$j,$j,$BNSZ	; j++
+	addi	$tp,$tp,$BNSZ	; tp++
+	bdnz-	L1st
+;L1st
+	addc	$lo0,$alo,$hi0
+	addze	$hi0,$ahi
+
+	addc	$lo1,$nlo,$hi1
+	addze	$hi1,$nhi
+	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[0]
+	addze	$hi1,$hi1
+	$ST	$lo1,0($tp)	; tp[j-1]
+
+	li	$ovf,0
+	addc	$hi1,$hi1,$hi0
+	addze	$ovf,$ovf	; upmost overflow bit
+	$ST	$hi1,$BNSZ($tp)
+
+	li	$i,$BNSZ
+.align	4
+Louter:
+	$LDX	$m0,$bp,$i	; m0=bp[i]
+	$LD	$aj,0($ap)	; ap[0]
+	addi	$tp,$sp,$FRAME
+	$LD	$tj,$FRAME($sp)	; tp[0]
+	$UMULL	$lo0,$aj,$m0	; ap[0]*bp[i]
+	$UMULH	$hi0,$aj,$m0
+	$LD	$aj,$BNSZ($ap)	; ap[1]
+	$LD	$nj,0($np)	; np[0]
+	addc	$lo0,$lo0,$tj	; ap[0]*bp[i]+tp[0]
+	$UMULL	$alo,$aj,$m0	; ap[j]*bp[i]
+	addze	$hi0,$hi0
+	$UMULL	$m1,$lo0,$n0	; tp[0]*n0
+	$UMULH	$ahi,$aj,$m0
+	$UMULL	$lo1,$nj,$m1	; np[0]*m1
+	$UMULH	$hi1,$nj,$m1
+	$LD	$nj,$BNSZ($np)	; np[1]
+	addc	$lo1,$lo1,$lo0
+	$UMULL	$nlo,$nj,$m1	; np[1]*m1
+	addze	$hi1,$hi1
+	$UMULH	$nhi,$nj,$m1
+
+	mtctr	$num
+	li	$j,`2*$BNSZ`
+.align	4
+Linner:
+	$LDX	$aj,$ap,$j	; ap[j]
+	addc	$lo0,$alo,$hi0
+	$LD	$tj,$BNSZ($tp)	; tp[j]
+	addze	$hi0,$ahi
+	$LDX	$nj,$np,$j	; np[j]
+	addc	$lo1,$nlo,$hi1
+	$UMULL	$alo,$aj,$m0	; ap[j]*bp[i]
+	addze	$hi1,$nhi
+	$UMULH	$ahi,$aj,$m0
+	addc	$lo0,$lo0,$tj	; ap[j]*bp[i]+tp[j]
+	$UMULL	$nlo,$nj,$m1	; np[j]*m1
+	addze	$hi0,$hi0
+	$UMULH	$nhi,$nj,$m1
+	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[i]+tp[j]
+	addi	$j,$j,$BNSZ	; j++
+	addze	$hi1,$hi1
+	$ST	$lo1,0($tp)	; tp[j-1]
+	addi	$tp,$tp,$BNSZ	; tp++
+	bdnz-	Linner
+;Linner
+	$LD	$tj,$BNSZ($tp)	; tp[j]
+	addc	$lo0,$alo,$hi0
+	addze	$hi0,$ahi
+	addc	$lo0,$lo0,$tj	; ap[j]*bp[i]+tp[j]
+	addze	$hi0,$hi0
+
+	addc	$lo1,$nlo,$hi1
+	addze	$hi1,$nhi
+	addc	$lo1,$lo1,$lo0	; np[j]*m1+ap[j]*bp[i]+tp[j]
+	addze	$hi1,$hi1
+	$ST	$lo1,0($tp)	; tp[j-1]
+
+	addic	$ovf,$ovf,-1	; move upmost overflow to XER[CA]
+	li	$ovf,0
+	adde	$hi1,$hi1,$hi0
+	addze	$ovf,$ovf
+	$ST	$hi1,$BNSZ($tp)
+;
+	slwi	$tj,$num,`log($BNSZ)/log(2)`
+	$UCMP	$i,$tj
+	addi	$i,$i,$BNSZ
+	ble-	Louter
+
+	addi	$num,$num,2	; restore $num
+	subfc	$j,$j,$j	; j=0 and "clear" XER[CA]
+	addi	$tp,$sp,$FRAME
+	mtctr	$num
+
+.align	4
+Lsub:	$LDX	$tj,$tp,$j
+	$LDX	$nj,$np,$j
+	subfe	$aj,$nj,$tj	; tp[j]-np[j]
+	$STX	$aj,$rp,$j
+	addi	$j,$j,$BNSZ
+	bdnz-	Lsub
+
+	li	$j,0
+	mtctr	$num
+	subfe	$ovf,$j,$ovf	; handle upmost overflow bit
+	and	$ap,$tp,$ovf
+	andc	$np,$rp,$ovf
+	or	$ap,$ap,$np	; ap=borrow?tp:rp
+
+.align	4
+Lcopy:				; copy or in-place refresh
+	$LDX	$tj,$ap,$j
+	$STX	$tj,$rp,$j
+	$STX	$j,$tp,$j	; zap at once
+	addi	$j,$j,$BNSZ
+	bdnz-	Lcopy
+
+	$POP	r14,`4*$SIZE_T`($sp)
+	$POP	r15,`5*$SIZE_T`($sp)
+	$POP	r16,`6*$SIZE_T`($sp)
+	$POP	r17,`7*$SIZE_T`($sp)
+	$POP	r18,`8*$SIZE_T`($sp)
+	$POP	r19,`9*$SIZE_T`($sp)
+	$POP	r20,`10*$SIZE_T`($sp)
+	$POP	r21,`11*$SIZE_T`($sp)
+	$POP	r22,`12*$SIZE_T`($sp)
+	$POP	r23,`13*$SIZE_T`($sp)
+	$POP	r24,`14*$SIZE_T`($sp)
+	$POP	r25,`15*$SIZE_T`($sp)
+	$POP	$sp,0($sp)
+	li	r3,1
+	blr
+	.long	0
+.asciz  "Montgomery Multiplication for PPC, CRYPTOGAMS by <appro\@fy.chalmers.se>"
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/crypto/bn/asm/ppc64-mont.pl b/crypto/bn/asm/ppc64-mont.pl
new file mode 100644
index 0000000..3449b35
--- /dev/null
+++ b/crypto/bn/asm/ppc64-mont.pl
@@ -0,0 +1,918 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# December 2007
+
+# The reason for undertaken effort is basically following. Even though
+# Power 6 CPU operates at incredible 4.7GHz clock frequency, its PKI
+# performance was observed to be less than impressive, essentially as
+# fast as 1.8GHz PPC970, or 2.6 times(!) slower than one would hope.
+# Well, it's not surprising that IBM had to make some sacrifices to
+# boost the clock frequency that much, but no overall improvement?
+# Having observed how much difference did switching to FPU make on
+# UltraSPARC, playing same stunt on Power 6 appeared appropriate...
+# Unfortunately the resulting performance improvement is not as
+# impressive, ~30%, and in absolute terms is still very far from what
+# one would expect from 4.7GHz CPU. There is a chance that I'm doing
+# something wrong, but in the lack of assembler level micro-profiling
+# data or at least decent platform guide I can't tell... Or better
+# results might be achieved with VMX... Anyway, this module provides
+# *worse* performance on other PowerPC implementations, ~40-15% slower
+# on PPC970 depending on key length and ~40% slower on Power 5 for all
+# key lengths. As it's obviously inappropriate as "best all-round"
+# alternative, it has to be complemented with run-time CPU family
+# detection. Oh! It should also be noted that unlike other PowerPC
+# implementation IALU ppc-mont.pl module performs *suboptimaly* on
+# >=1024-bit key lengths on Power 6. It should also be noted that
+# *everything* said so far applies to 64-bit builds! As far as 32-bit
+# application executed on 64-bit CPU goes, this module is likely to
+# become preferred choice, because it's easy to adapt it for such
+# case and *is* faster than 32-bit ppc-mont.pl on *all* processors.
+
+# February 2008
+
+# Micro-profiling assisted optimization results in ~15% improvement
+# over original ppc64-mont.pl version, or overall ~50% improvement
+# over ppc.pl module on Power 6. If compared to ppc-mont.pl on same
+# Power 6 CPU, this module is 5-150% faster depending on key length,
+# [hereafter] more for longer keys. But if compared to ppc-mont.pl
+# on 1.8GHz PPC970, it's only 5-55% faster. Still far from impressive
+# in absolute terms, but it's apparently the way Power 6 is...
+
+$flavour = shift;
+
+if ($flavour =~ /32/) {
+	$SIZE_T=4;
+	$RZONE=	224;
+	$FRAME=	$SIZE_T*12+8*12;
+	$fname=	"bn_mul_mont_ppc64";
+
+	$STUX=	"stwux";	# store indexed and update
+	$PUSH=	"stw";
+	$POP=	"lwz";
+	die "not implemented yet";
+} elsif ($flavour =~ /64/) {
+	$SIZE_T=8;
+	$RZONE=	288;
+	$FRAME=	$SIZE_T*12+8*12;
+	$fname=	"bn_mul_mont";
+
+	# same as above, but 64-bit mnemonics...
+	$STUX=	"stdux";	# store indexed and update
+	$PUSH=	"std";
+	$POP=	"ld";
+} else { die "nonsense $flavour"; }
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
+die "can't locate ppc-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
+
+$FRAME=($FRAME+63)&~63;
+$TRANSFER=16*8;
+
+$carry="r0";
+$sp="r1";
+$toc="r2";
+$rp="r3";	$ovf="r3";
+$ap="r4";
+$bp="r5";
+$np="r6";
+$n0="r7";
+$num="r8";
+$rp="r9";	# $rp is reassigned
+$tp="r10";
+$j="r11";
+$i="r12";
+# non-volatile registers
+$nap_d="r14";	# interleaved ap and np in double format
+$a0="r15";	# ap[0]
+$t0="r16";	# temporary registers
+$t1="r17";
+$t2="r18";
+$t3="r19";
+$t4="r20";
+$t5="r21";
+$t6="r22";
+$t7="r23";
+
+# PPC offers enough register bank capacity to unroll inner loops twice
+#
+#     ..A3A2A1A0
+#           dcba
+#    -----------
+#            A0a
+#           A0b
+#          A0c
+#         A0d
+#          A1a
+#         A1b
+#        A1c
+#       A1d
+#        A2a
+#       A2b
+#      A2c
+#     A2d
+#      A3a
+#     A3b
+#    A3c
+#   A3d
+#    ..a
+#   ..b
+#
+$ba="f0";	$bb="f1";	$bc="f2";	$bd="f3";
+$na="f4";	$nb="f5";	$nc="f6";	$nd="f7";
+$dota="f8";	$dotb="f9";
+$A0="f10";	$A1="f11";	$A2="f12";	$A3="f13";
+$N0="f14";	$N1="f15";	$N2="f16";	$N3="f17";
+$T0a="f18";	$T0b="f19";
+$T1a="f20";	$T1b="f21";
+$T2a="f22";	$T2b="f23";
+$T3a="f24";	$T3b="f25";
+
+# sp----------->+-------------------------------+
+#		| saved sp			|
+#		+-------------------------------+
+#		|				|
+#		+-------------------------------+
+#		| 10 saved gpr, r14-r23		|
+#		.				.
+#		.				.
+#   +12*size_t	+-------------------------------+
+#		| 12 saved fpr, f14-f25		|
+#		.				.
+#		.				.
+#   +12*8	+-------------------------------+
+#		| padding to 64 byte boundary	|
+#		.				.
+#   +X		+-------------------------------+
+#		| 16 gpr<->fpr transfer zone	|
+#		.				.
+#		.				.
+#   +16*8	+-------------------------------+
+#		| __int64 tmp[-1]		|
+#		+-------------------------------+
+#		| __int64 tmp[num]		|
+#		.				.
+#		.				.
+#		.				.
+#   +(num+1)*8	+-------------------------------+
+#		| padding to 64 byte boundary	|
+#		.				.
+#   +X		+-------------------------------+
+#		| double nap_d[4*num]		|
+#		.				.
+#		.				.
+#		.				.
+#		+-------------------------------+
+
+$code=<<___;
+.machine "any"
+.text
+
+.globl	.$fname
+.align	5
+.$fname:
+	cmpwi	$num,4
+	mr	$rp,r3		; $rp is reassigned
+	li	r3,0		; possible "not handled" return code
+	bltlr-
+	andi.	r0,$num,1	; $num has to be even
+	bnelr-
+
+	slwi	$num,$num,3	; num*=8
+	li	$i,-4096
+	slwi	$tp,$num,2	; place for {an}p_{lh}[num], i.e. 4*num
+	add	$tp,$tp,$num	; place for tp[num+1]
+	addi	$tp,$tp,`$FRAME+$TRANSFER+8+64+$RZONE`
+	subf	$tp,$tp,$sp	; $sp-$tp
+	and	$tp,$tp,$i	; minimize TLB usage
+	subf	$tp,$sp,$tp	; $tp-$sp
+	$STUX	$sp,$sp,$tp	; alloca
+
+	$PUSH	r14,`2*$SIZE_T`($sp)
+	$PUSH	r15,`3*$SIZE_T`($sp)
+	$PUSH	r16,`4*$SIZE_T`($sp)
+	$PUSH	r17,`5*$SIZE_T`($sp)
+	$PUSH	r18,`6*$SIZE_T`($sp)
+	$PUSH	r19,`7*$SIZE_T`($sp)
+	$PUSH	r20,`8*$SIZE_T`($sp)
+	$PUSH	r21,`9*$SIZE_T`($sp)
+	$PUSH	r22,`10*$SIZE_T`($sp)
+	$PUSH	r23,`11*$SIZE_T`($sp)
+	stfd	f14,`12*$SIZE_T+0`($sp)
+	stfd	f15,`12*$SIZE_T+8`($sp)
+	stfd	f16,`12*$SIZE_T+16`($sp)
+	stfd	f17,`12*$SIZE_T+24`($sp)
+	stfd	f18,`12*$SIZE_T+32`($sp)
+	stfd	f19,`12*$SIZE_T+40`($sp)
+	stfd	f20,`12*$SIZE_T+48`($sp)
+	stfd	f21,`12*$SIZE_T+56`($sp)
+	stfd	f22,`12*$SIZE_T+64`($sp)
+	stfd	f23,`12*$SIZE_T+72`($sp)
+	stfd	f24,`12*$SIZE_T+80`($sp)
+	stfd	f25,`12*$SIZE_T+88`($sp)
+
+	ld	$a0,0($ap)	; pull ap[0] value
+	ld	$n0,0($n0)	; pull n0[0] value
+	ld	$t3,0($bp)	; bp[0]
+
+	addi	$tp,$sp,`$FRAME+$TRANSFER+8+64`
+	li	$i,-64
+	add	$nap_d,$tp,$num
+	and	$nap_d,$nap_d,$i	; align to 64 bytes
+
+	mulld	$t7,$a0,$t3	; ap[0]*bp[0]
+	; nap_d is off by 1, because it's used with stfdu/lfdu
+	addi	$nap_d,$nap_d,-8
+	srwi	$j,$num,`3+1`	; counter register, num/2
+	mulld	$t7,$t7,$n0	; tp[0]*n0
+	addi	$j,$j,-1
+	addi	$tp,$sp,`$FRAME+$TRANSFER-8`
+	li	$carry,0
+	mtctr	$j
+
+	; transfer bp[0] to FPU as 4x16-bit values
+	extrdi	$t0,$t3,16,48
+	extrdi	$t1,$t3,16,32
+	extrdi	$t2,$t3,16,16
+	extrdi	$t3,$t3,16,0
+	std	$t0,`$FRAME+0`($sp)
+	std	$t1,`$FRAME+8`($sp)
+	std	$t2,`$FRAME+16`($sp)
+	std	$t3,`$FRAME+24`($sp)
+	; transfer (ap[0]*bp[0])*n0 to FPU as 4x16-bit values
+	extrdi	$t4,$t7,16,48
+	extrdi	$t5,$t7,16,32
+	extrdi	$t6,$t7,16,16
+	extrdi	$t7,$t7,16,0
+	std	$t4,`$FRAME+32`($sp)
+	std	$t5,`$FRAME+40`($sp)
+	std	$t6,`$FRAME+48`($sp)
+	std	$t7,`$FRAME+56`($sp)
+	lwz	$t0,4($ap)		; load a[j] as 32-bit word pair
+	lwz	$t1,0($ap)
+	lwz	$t2,12($ap)		; load a[j+1] as 32-bit word pair
+	lwz	$t3,8($ap)
+	lwz	$t4,4($np)		; load n[j] as 32-bit word pair
+	lwz	$t5,0($np)
+	lwz	$t6,12($np)		; load n[j+1] as 32-bit word pair
+	lwz	$t7,8($np)
+	lfd	$ba,`$FRAME+0`($sp)
+	lfd	$bb,`$FRAME+8`($sp)
+	lfd	$bc,`$FRAME+16`($sp)
+	lfd	$bd,`$FRAME+24`($sp)
+	lfd	$na,`$FRAME+32`($sp)
+	lfd	$nb,`$FRAME+40`($sp)
+	lfd	$nc,`$FRAME+48`($sp)
+	lfd	$nd,`$FRAME+56`($sp)
+	std	$t0,`$FRAME+64`($sp)
+	std	$t1,`$FRAME+72`($sp)
+	std	$t2,`$FRAME+80`($sp)
+	std	$t3,`$FRAME+88`($sp)
+	std	$t4,`$FRAME+96`($sp)
+	std	$t5,`$FRAME+104`($sp)
+	std	$t6,`$FRAME+112`($sp)
+	std	$t7,`$FRAME+120`($sp)
+	fcfid	$ba,$ba
+	fcfid	$bb,$bb
+	fcfid	$bc,$bc
+	fcfid	$bd,$bd
+	fcfid	$na,$na
+	fcfid	$nb,$nb
+	fcfid	$nc,$nc
+	fcfid	$nd,$nd
+
+	lfd	$A0,`$FRAME+64`($sp)
+	lfd	$A1,`$FRAME+72`($sp)
+	lfd	$A2,`$FRAME+80`($sp)
+	lfd	$A3,`$FRAME+88`($sp)
+	lfd	$N0,`$FRAME+96`($sp)
+	lfd	$N1,`$FRAME+104`($sp)
+	lfd	$N2,`$FRAME+112`($sp)
+	lfd	$N3,`$FRAME+120`($sp)
+	fcfid	$A0,$A0
+	fcfid	$A1,$A1
+	fcfid	$A2,$A2
+	fcfid	$A3,$A3
+	fcfid	$N0,$N0
+	fcfid	$N1,$N1
+	fcfid	$N2,$N2
+	fcfid	$N3,$N3
+	addi	$ap,$ap,16
+	addi	$np,$np,16
+
+	fmul	$T1a,$A1,$ba
+	fmul	$T1b,$A1,$bb
+	stfd	$A0,8($nap_d)		; save a[j] in double format
+	stfd	$A1,16($nap_d)
+	fmul	$T2a,$A2,$ba
+	fmul	$T2b,$A2,$bb
+	stfd	$A2,24($nap_d)		; save a[j+1] in double format
+	stfd	$A3,32($nap_d)
+	fmul	$T3a,$A3,$ba
+	fmul	$T3b,$A3,$bb
+	stfd	$N0,40($nap_d)		; save n[j] in double format
+	stfd	$N1,48($nap_d)
+	fmul	$T0a,$A0,$ba
+	fmul	$T0b,$A0,$bb
+	stfd	$N2,56($nap_d)		; save n[j+1] in double format
+	stfdu	$N3,64($nap_d)
+
+	fmadd	$T1a,$A0,$bc,$T1a
+	fmadd	$T1b,$A0,$bd,$T1b
+	fmadd	$T2a,$A1,$bc,$T2a
+	fmadd	$T2b,$A1,$bd,$T2b
+	fmadd	$T3a,$A2,$bc,$T3a
+	fmadd	$T3b,$A2,$bd,$T3b
+	fmul	$dota,$A3,$bc
+	fmul	$dotb,$A3,$bd
+
+	fmadd	$T1a,$N1,$na,$T1a
+	fmadd	$T1b,$N1,$nb,$T1b
+	fmadd	$T2a,$N2,$na,$T2a
+	fmadd	$T2b,$N2,$nb,$T2b
+	fmadd	$T3a,$N3,$na,$T3a
+	fmadd	$T3b,$N3,$nb,$T3b
+	fmadd	$T0a,$N0,$na,$T0a
+	fmadd	$T0b,$N0,$nb,$T0b
+
+	fmadd	$T1a,$N0,$nc,$T1a
+	fmadd	$T1b,$N0,$nd,$T1b
+	fmadd	$T2a,$N1,$nc,$T2a
+	fmadd	$T2b,$N1,$nd,$T2b
+	fmadd	$T3a,$N2,$nc,$T3a
+	fmadd	$T3b,$N2,$nd,$T3b
+	fmadd	$dota,$N3,$nc,$dota
+	fmadd	$dotb,$N3,$nd,$dotb
+
+	fctid	$T0a,$T0a
+	fctid	$T0b,$T0b
+	fctid	$T1a,$T1a
+	fctid	$T1b,$T1b
+	fctid	$T2a,$T2a
+	fctid	$T2b,$T2b
+	fctid	$T3a,$T3a
+	fctid	$T3b,$T3b
+
+	stfd	$T0a,`$FRAME+0`($sp)
+	stfd	$T0b,`$FRAME+8`($sp)
+	stfd	$T1a,`$FRAME+16`($sp)
+	stfd	$T1b,`$FRAME+24`($sp)
+	stfd	$T2a,`$FRAME+32`($sp)
+	stfd	$T2b,`$FRAME+40`($sp)
+	stfd	$T3a,`$FRAME+48`($sp)
+	stfd	$T3b,`$FRAME+56`($sp)
+
+.align	5
+L1st:
+	lwz	$t0,4($ap)		; load a[j] as 32-bit word pair
+	lwz	$t1,0($ap)
+	lwz	$t2,12($ap)		; load a[j+1] as 32-bit word pair
+	lwz	$t3,8($ap)
+	lwz	$t4,4($np)		; load n[j] as 32-bit word pair
+	lwz	$t5,0($np)
+	lwz	$t6,12($np)		; load n[j+1] as 32-bit word pair
+	lwz	$t7,8($np)
+	std	$t0,`$FRAME+64`($sp)
+	std	$t1,`$FRAME+72`($sp)
+	std	$t2,`$FRAME+80`($sp)
+	std	$t3,`$FRAME+88`($sp)
+	std	$t4,`$FRAME+96`($sp)
+	std	$t5,`$FRAME+104`($sp)
+	std	$t6,`$FRAME+112`($sp)
+	std	$t7,`$FRAME+120`($sp)
+	ld	$t0,`$FRAME+0`($sp)
+	ld	$t1,`$FRAME+8`($sp)
+	ld	$t2,`$FRAME+16`($sp)
+	ld	$t3,`$FRAME+24`($sp)
+	ld	$t4,`$FRAME+32`($sp)
+	ld	$t5,`$FRAME+40`($sp)
+	ld	$t6,`$FRAME+48`($sp)
+	ld	$t7,`$FRAME+56`($sp)
+	lfd	$A0,`$FRAME+64`($sp)
+	lfd	$A1,`$FRAME+72`($sp)
+	lfd	$A2,`$FRAME+80`($sp)
+	lfd	$A3,`$FRAME+88`($sp)
+	lfd	$N0,`$FRAME+96`($sp)
+	lfd	$N1,`$FRAME+104`($sp)
+	lfd	$N2,`$FRAME+112`($sp)
+	lfd	$N3,`$FRAME+120`($sp)
+	fcfid	$A0,$A0
+	fcfid	$A1,$A1
+	fcfid	$A2,$A2
+	fcfid	$A3,$A3
+	fcfid	$N0,$N0
+	fcfid	$N1,$N1
+	fcfid	$N2,$N2
+	fcfid	$N3,$N3
+	addi	$ap,$ap,16
+	addi	$np,$np,16
+
+	fmul	$T1a,$A1,$ba
+	fmul	$T1b,$A1,$bb
+	fmul	$T2a,$A2,$ba
+	fmul	$T2b,$A2,$bb
+	stfd	$A0,8($nap_d)		; save a[j] in double format
+	stfd	$A1,16($nap_d)
+	fmul	$T3a,$A3,$ba
+	fmul	$T3b,$A3,$bb
+	fmadd	$T0a,$A0,$ba,$dota
+	fmadd	$T0b,$A0,$bb,$dotb
+	stfd	$A2,24($nap_d)		; save a[j+1] in double format
+	stfd	$A3,32($nap_d)
+
+	fmadd	$T1a,$A0,$bc,$T1a
+	fmadd	$T1b,$A0,$bd,$T1b
+	fmadd	$T2a,$A1,$bc,$T2a
+	fmadd	$T2b,$A1,$bd,$T2b
+	stfd	$N0,40($nap_d)		; save n[j] in double format
+	stfd	$N1,48($nap_d)
+	fmadd	$T3a,$A2,$bc,$T3a
+	fmadd	$T3b,$A2,$bd,$T3b
+	 add	$t0,$t0,$carry		; can not overflow
+	fmul	$dota,$A3,$bc
+	fmul	$dotb,$A3,$bd
+	stfd	$N2,56($nap_d)		; save n[j+1] in double format
+	stfdu	$N3,64($nap_d)
+	 srdi	$carry,$t0,16
+	 add	$t1,$t1,$carry
+	 srdi	$carry,$t1,16
+
+	fmadd	$T1a,$N1,$na,$T1a
+	fmadd	$T1b,$N1,$nb,$T1b
+	 insrdi	$t0,$t1,16,32
+	fmadd	$T2a,$N2,$na,$T2a
+	fmadd	$T2b,$N2,$nb,$T2b
+	 add	$t2,$t2,$carry
+	fmadd	$T3a,$N3,$na,$T3a
+	fmadd	$T3b,$N3,$nb,$T3b
+	 srdi	$carry,$t2,16
+	fmadd	$T0a,$N0,$na,$T0a
+	fmadd	$T0b,$N0,$nb,$T0b
+	 insrdi	$t0,$t2,16,16
+	 add	$t3,$t3,$carry
+	 srdi	$carry,$t3,16
+
+	fmadd	$T1a,$N0,$nc,$T1a
+	fmadd	$T1b,$N0,$nd,$T1b
+	 insrdi	$t0,$t3,16,0		; 0..63 bits
+	fmadd	$T2a,$N1,$nc,$T2a
+	fmadd	$T2b,$N1,$nd,$T2b
+	 add	$t4,$t4,$carry
+	fmadd	$T3a,$N2,$nc,$T3a
+	fmadd	$T3b,$N2,$nd,$T3b
+	 srdi	$carry,$t4,16
+	fmadd	$dota,$N3,$nc,$dota
+	fmadd	$dotb,$N3,$nd,$dotb
+	 add	$t5,$t5,$carry
+	 srdi	$carry,$t5,16
+	 insrdi	$t4,$t5,16,32
+
+	fctid	$T0a,$T0a
+	fctid	$T0b,$T0b
+	 add	$t6,$t6,$carry
+	fctid	$T1a,$T1a
+	fctid	$T1b,$T1b
+	 srdi	$carry,$t6,16
+	fctid	$T2a,$T2a
+	fctid	$T2b,$T2b
+	 insrdi	$t4,$t6,16,16
+	fctid	$T3a,$T3a
+	fctid	$T3b,$T3b
+	 add	$t7,$t7,$carry
+	 insrdi	$t4,$t7,16,0		; 64..127 bits
+	 srdi	$carry,$t7,16		; upper 33 bits
+
+	stfd	$T0a,`$FRAME+0`($sp)
+	stfd	$T0b,`$FRAME+8`($sp)
+	stfd	$T1a,`$FRAME+16`($sp)
+	stfd	$T1b,`$FRAME+24`($sp)
+	stfd	$T2a,`$FRAME+32`($sp)
+	stfd	$T2b,`$FRAME+40`($sp)
+	stfd	$T3a,`$FRAME+48`($sp)
+	stfd	$T3b,`$FRAME+56`($sp)
+	 std	$t0,8($tp)		; tp[j-1]
+	 stdu	$t4,16($tp)		; tp[j]
+	bdnz-	L1st
+
+	fctid	$dota,$dota
+	fctid	$dotb,$dotb
+
+	ld	$t0,`$FRAME+0`($sp)
+	ld	$t1,`$FRAME+8`($sp)
+	ld	$t2,`$FRAME+16`($sp)
+	ld	$t3,`$FRAME+24`($sp)
+	ld	$t4,`$FRAME+32`($sp)
+	ld	$t5,`$FRAME+40`($sp)
+	ld	$t6,`$FRAME+48`($sp)
+	ld	$t7,`$FRAME+56`($sp)
+	stfd	$dota,`$FRAME+64`($sp)
+	stfd	$dotb,`$FRAME+72`($sp)
+
+	add	$t0,$t0,$carry		; can not overflow
+	srdi	$carry,$t0,16
+	add	$t1,$t1,$carry
+	srdi	$carry,$t1,16
+	insrdi	$t0,$t1,16,32
+	add	$t2,$t2,$carry
+	srdi	$carry,$t2,16
+	insrdi	$t0,$t2,16,16
+	add	$t3,$t3,$carry
+	srdi	$carry,$t3,16
+	insrdi	$t0,$t3,16,0		; 0..63 bits
+	add	$t4,$t4,$carry
+	srdi	$carry,$t4,16
+	add	$t5,$t5,$carry
+	srdi	$carry,$t5,16
+	insrdi	$t4,$t5,16,32
+	add	$t6,$t6,$carry
+	srdi	$carry,$t6,16
+	insrdi	$t4,$t6,16,16
+	add	$t7,$t7,$carry
+	insrdi	$t4,$t7,16,0		; 64..127 bits
+	srdi	$carry,$t7,16		; upper 33 bits
+	ld	$t6,`$FRAME+64`($sp)
+	ld	$t7,`$FRAME+72`($sp)
+
+	std	$t0,8($tp)		; tp[j-1]
+	stdu	$t4,16($tp)		; tp[j]
+
+	add	$t6,$t6,$carry		; can not overflow
+	srdi	$carry,$t6,16
+	add	$t7,$t7,$carry
+	insrdi	$t6,$t7,48,0
+	srdi	$ovf,$t7,48
+	std	$t6,8($tp)		; tp[num-1]
+
+	slwi	$t7,$num,2
+	subf	$nap_d,$t7,$nap_d	; rewind pointer
+
+	li	$i,8			; i=1
+.align	5
+Louter:
+	ldx	$t3,$bp,$i	; bp[i]
+	ld	$t6,`$FRAME+$TRANSFER+8`($sp)	; tp[0]
+	mulld	$t7,$a0,$t3	; ap[0]*bp[i]
+
+	addi	$tp,$sp,`$FRAME+$TRANSFER`
+	add	$t7,$t7,$t6	; ap[0]*bp[i]+tp[0]
+	li	$carry,0
+	mulld	$t7,$t7,$n0	; tp[0]*n0
+	mtctr	$j
+
+	; transfer bp[i] to FPU as 4x16-bit values
+	extrdi	$t0,$t3,16,48
+	extrdi	$t1,$t3,16,32
+	extrdi	$t2,$t3,16,16
+	extrdi	$t3,$t3,16,0
+	std	$t0,`$FRAME+0`($sp)
+	std	$t1,`$FRAME+8`($sp)
+	std	$t2,`$FRAME+16`($sp)
+	std	$t3,`$FRAME+24`($sp)
+	; transfer (ap[0]*bp[i]+tp[0])*n0 to FPU as 4x16-bit values
+	extrdi	$t4,$t7,16,48
+	extrdi	$t5,$t7,16,32
+	extrdi	$t6,$t7,16,16
+	extrdi	$t7,$t7,16,0
+	std	$t4,`$FRAME+32`($sp)
+	std	$t5,`$FRAME+40`($sp)
+	std	$t6,`$FRAME+48`($sp)
+	std	$t7,`$FRAME+56`($sp)
+
+	lfd	$A0,8($nap_d)		; load a[j] in double format
+	lfd	$A1,16($nap_d)
+	lfd	$A2,24($nap_d)		; load a[j+1] in double format
+	lfd	$A3,32($nap_d)
+	lfd	$N0,40($nap_d)		; load n[j] in double format
+	lfd	$N1,48($nap_d)
+	lfd	$N2,56($nap_d)		; load n[j+1] in double format
+	lfdu	$N3,64($nap_d)
+
+	lfd	$ba,`$FRAME+0`($sp)
+	lfd	$bb,`$FRAME+8`($sp)
+	lfd	$bc,`$FRAME+16`($sp)
+	lfd	$bd,`$FRAME+24`($sp)
+	lfd	$na,`$FRAME+32`($sp)
+	lfd	$nb,`$FRAME+40`($sp)
+	lfd	$nc,`$FRAME+48`($sp)
+	lfd	$nd,`$FRAME+56`($sp)
+
+	fcfid	$ba,$ba
+	fcfid	$bb,$bb
+	fcfid	$bc,$bc
+	fcfid	$bd,$bd
+	fcfid	$na,$na
+	fcfid	$nb,$nb
+	fcfid	$nc,$nc
+	fcfid	$nd,$nd
+
+	fmul	$T1a,$A1,$ba
+	fmul	$T1b,$A1,$bb
+	fmul	$T2a,$A2,$ba
+	fmul	$T2b,$A2,$bb
+	fmul	$T3a,$A3,$ba
+	fmul	$T3b,$A3,$bb
+	fmul	$T0a,$A0,$ba
+	fmul	$T0b,$A0,$bb
+
+	fmadd	$T1a,$A0,$bc,$T1a
+	fmadd	$T1b,$A0,$bd,$T1b
+	fmadd	$T2a,$A1,$bc,$T2a
+	fmadd	$T2b,$A1,$bd,$T2b
+	fmadd	$T3a,$A2,$bc,$T3a
+	fmadd	$T3b,$A2,$bd,$T3b
+	fmul	$dota,$A3,$bc
+	fmul	$dotb,$A3,$bd
+
+	fmadd	$T1a,$N1,$na,$T1a
+	fmadd	$T1b,$N1,$nb,$T1b
+	 lfd	$A0,8($nap_d)		; load a[j] in double format
+	 lfd	$A1,16($nap_d)
+	fmadd	$T2a,$N2,$na,$T2a
+	fmadd	$T2b,$N2,$nb,$T2b
+	 lfd	$A2,24($nap_d)		; load a[j+1] in double format
+	 lfd	$A3,32($nap_d)
+	fmadd	$T3a,$N3,$na,$T3a
+	fmadd	$T3b,$N3,$nb,$T3b
+	fmadd	$T0a,$N0,$na,$T0a
+	fmadd	$T0b,$N0,$nb,$T0b
+
+	fmadd	$T1a,$N0,$nc,$T1a
+	fmadd	$T1b,$N0,$nd,$T1b
+	fmadd	$T2a,$N1,$nc,$T2a
+	fmadd	$T2b,$N1,$nd,$T2b
+	fmadd	$T3a,$N2,$nc,$T3a
+	fmadd	$T3b,$N2,$nd,$T3b
+	fmadd	$dota,$N3,$nc,$dota
+	fmadd	$dotb,$N3,$nd,$dotb
+
+	fctid	$T0a,$T0a
+	fctid	$T0b,$T0b
+	fctid	$T1a,$T1a
+	fctid	$T1b,$T1b
+	fctid	$T2a,$T2a
+	fctid	$T2b,$T2b
+	fctid	$T3a,$T3a
+	fctid	$T3b,$T3b
+
+	stfd	$T0a,`$FRAME+0`($sp)
+	stfd	$T0b,`$FRAME+8`($sp)
+	stfd	$T1a,`$FRAME+16`($sp)
+	stfd	$T1b,`$FRAME+24`($sp)
+	stfd	$T2a,`$FRAME+32`($sp)
+	stfd	$T2b,`$FRAME+40`($sp)
+	stfd	$T3a,`$FRAME+48`($sp)
+	stfd	$T3b,`$FRAME+56`($sp)
+
+.align	5
+Linner:
+	fmul	$T1a,$A1,$ba
+	fmul	$T1b,$A1,$bb
+	fmul	$T2a,$A2,$ba
+	fmul	$T2b,$A2,$bb
+	lfd	$N0,40($nap_d)		; load n[j] in double format
+	lfd	$N1,48($nap_d)
+	fmul	$T3a,$A3,$ba
+	fmul	$T3b,$A3,$bb
+	fmadd	$T0a,$A0,$ba,$dota
+	fmadd	$T0b,$A0,$bb,$dotb
+	lfd	$N2,56($nap_d)		; load n[j+1] in double format
+	lfdu	$N3,64($nap_d)
+
+	fmadd	$T1a,$A0,$bc,$T1a
+	fmadd	$T1b,$A0,$bd,$T1b
+	fmadd	$T2a,$A1,$bc,$T2a
+	fmadd	$T2b,$A1,$bd,$T2b
+	 lfd	$A0,8($nap_d)		; load a[j] in double format
+	 lfd	$A1,16($nap_d)
+	fmadd	$T3a,$A2,$bc,$T3a
+	fmadd	$T3b,$A2,$bd,$T3b
+	fmul	$dota,$A3,$bc
+	fmul	$dotb,$A3,$bd
+	 lfd	$A2,24($nap_d)		; load a[j+1] in double format
+	 lfd	$A3,32($nap_d)
+
+	fmadd	$T1a,$N1,$na,$T1a
+	fmadd	$T1b,$N1,$nb,$T1b
+	 ld	$t0,`$FRAME+0`($sp)
+	 ld	$t1,`$FRAME+8`($sp)
+	fmadd	$T2a,$N2,$na,$T2a
+	fmadd	$T2b,$N2,$nb,$T2b
+	 ld	$t2,`$FRAME+16`($sp)
+	 ld	$t3,`$FRAME+24`($sp)
+	fmadd	$T3a,$N3,$na,$T3a
+	fmadd	$T3b,$N3,$nb,$T3b
+	 add	$t0,$t0,$carry		; can not overflow
+	 ld	$t4,`$FRAME+32`($sp)
+	 ld	$t5,`$FRAME+40`($sp)
+	fmadd	$T0a,$N0,$na,$T0a
+	fmadd	$T0b,$N0,$nb,$T0b
+	 srdi	$carry,$t0,16
+	 add	$t1,$t1,$carry
+	 srdi	$carry,$t1,16
+	 ld	$t6,`$FRAME+48`($sp)
+	 ld	$t7,`$FRAME+56`($sp)
+
+	fmadd	$T1a,$N0,$nc,$T1a
+	fmadd	$T1b,$N0,$nd,$T1b
+	 insrdi	$t0,$t1,16,32
+	 ld	$t1,8($tp)		; tp[j]
+	fmadd	$T2a,$N1,$nc,$T2a
+	fmadd	$T2b,$N1,$nd,$T2b
+	 add	$t2,$t2,$carry
+	fmadd	$T3a,$N2,$nc,$T3a
+	fmadd	$T3b,$N2,$nd,$T3b
+	 srdi	$carry,$t2,16
+	 insrdi	$t0,$t2,16,16
+	fmadd	$dota,$N3,$nc,$dota
+	fmadd	$dotb,$N3,$nd,$dotb
+	 add	$t3,$t3,$carry
+	 ldu	$t2,16($tp)		; tp[j+1]
+	 srdi	$carry,$t3,16
+	 insrdi	$t0,$t3,16,0		; 0..63 bits
+	 add	$t4,$t4,$carry
+
+	fctid	$T0a,$T0a
+	fctid	$T0b,$T0b
+	 srdi	$carry,$t4,16
+	fctid	$T1a,$T1a
+	fctid	$T1b,$T1b
+	 add	$t5,$t5,$carry
+	fctid	$T2a,$T2a
+	fctid	$T2b,$T2b
+	 srdi	$carry,$t5,16
+	 insrdi	$t4,$t5,16,32
+	fctid	$T3a,$T3a
+	fctid	$T3b,$T3b
+	 add	$t6,$t6,$carry
+	 srdi	$carry,$t6,16
+	 insrdi	$t4,$t6,16,16
+
+	stfd	$T0a,`$FRAME+0`($sp)
+	stfd	$T0b,`$FRAME+8`($sp)
+	 add	$t7,$t7,$carry
+	 addc	$t3,$t0,$t1
+	stfd	$T1a,`$FRAME+16`($sp)
+	stfd	$T1b,`$FRAME+24`($sp)
+	 insrdi	$t4,$t7,16,0		; 64..127 bits
+	 srdi	$carry,$t7,16		; upper 33 bits
+	stfd	$T2a,`$FRAME+32`($sp)
+	stfd	$T2b,`$FRAME+40`($sp)
+	 adde	$t5,$t4,$t2
+	stfd	$T3a,`$FRAME+48`($sp)
+	stfd	$T3b,`$FRAME+56`($sp)
+	 addze	$carry,$carry
+	 std	$t3,-16($tp)		; tp[j-1]
+	 std	$t5,-8($tp)		; tp[j]
+	bdnz-	Linner
+
+	fctid	$dota,$dota
+	fctid	$dotb,$dotb
+	ld	$t0,`$FRAME+0`($sp)
+	ld	$t1,`$FRAME+8`($sp)
+	ld	$t2,`$FRAME+16`($sp)
+	ld	$t3,`$FRAME+24`($sp)
+	ld	$t4,`$FRAME+32`($sp)
+	ld	$t5,`$FRAME+40`($sp)
+	ld	$t6,`$FRAME+48`($sp)
+	ld	$t7,`$FRAME+56`($sp)
+	stfd	$dota,`$FRAME+64`($sp)
+	stfd	$dotb,`$FRAME+72`($sp)
+
+	add	$t0,$t0,$carry		; can not overflow
+	srdi	$carry,$t0,16
+	add	$t1,$t1,$carry
+	srdi	$carry,$t1,16
+	insrdi	$t0,$t1,16,32
+	add	$t2,$t2,$carry
+	ld	$t1,8($tp)		; tp[j]
+	srdi	$carry,$t2,16
+	insrdi	$t0,$t2,16,16
+	add	$t3,$t3,$carry
+	ldu	$t2,16($tp)		; tp[j+1]
+	srdi	$carry,$t3,16
+	insrdi	$t0,$t3,16,0		; 0..63 bits
+	add	$t4,$t4,$carry
+	srdi	$carry,$t4,16
+	add	$t5,$t5,$carry
+	srdi	$carry,$t5,16
+	insrdi	$t4,$t5,16,32
+	add	$t6,$t6,$carry
+	srdi	$carry,$t6,16
+	insrdi	$t4,$t6,16,16
+	add	$t7,$t7,$carry
+	insrdi	$t4,$t7,16,0		; 64..127 bits
+	srdi	$carry,$t7,16		; upper 33 bits
+	ld	$t6,`$FRAME+64`($sp)
+	ld	$t7,`$FRAME+72`($sp)
+
+	addc	$t3,$t0,$t1
+	adde	$t5,$t4,$t2
+	addze	$carry,$carry
+
+	std	$t3,-16($tp)		; tp[j-1]
+	std	$t5,-8($tp)		; tp[j]
+
+	add	$carry,$carry,$ovf	; comsume upmost overflow
+	add	$t6,$t6,$carry		; can not overflow
+	srdi	$carry,$t6,16
+	add	$t7,$t7,$carry
+	insrdi	$t6,$t7,48,0
+	srdi	$ovf,$t7,48
+	std	$t6,0($tp)		; tp[num-1]
+
+	slwi	$t7,$num,2
+	addi	$i,$i,8
+	subf	$nap_d,$t7,$nap_d	; rewind pointer
+	cmpw	$i,$num
+	blt-	Louter
+
+	subf	$np,$num,$np	; rewind np
+	addi	$j,$j,1		; restore counter
+	subfc	$i,$i,$i	; j=0 and "clear" XER[CA]
+	addi	$tp,$sp,`$FRAME+$TRANSFER+8`
+	addi	$t4,$sp,`$FRAME+$TRANSFER+16`
+	addi	$t5,$np,8
+	addi	$t6,$rp,8
+	mtctr	$j
+
+.align	4
+Lsub:	ldx	$t0,$tp,$i
+	ldx	$t1,$np,$i
+	ldx	$t2,$t4,$i
+	ldx	$t3,$t5,$i
+	subfe	$t0,$t1,$t0	; tp[j]-np[j]
+	subfe	$t2,$t3,$t2	; tp[j+1]-np[j+1]
+	stdx	$t0,$rp,$i
+	stdx	$t2,$t6,$i
+	addi	$i,$i,16
+	bdnz-	Lsub
+
+	li	$i,0
+	subfe	$ovf,$i,$ovf	; handle upmost overflow bit
+	and	$ap,$tp,$ovf
+	andc	$np,$rp,$ovf
+	or	$ap,$ap,$np	; ap=borrow?tp:rp
+	addi	$t7,$ap,8
+	mtctr	$j
+
+.align	4
+Lcopy:				; copy or in-place refresh
+	ldx	$t0,$ap,$i
+	ldx	$t1,$t7,$i
+	std	$i,8($nap_d)	; zap nap_d
+	std	$i,16($nap_d)
+	std	$i,24($nap_d)
+	std	$i,32($nap_d)
+	std	$i,40($nap_d)
+	std	$i,48($nap_d)
+	std	$i,56($nap_d)
+	stdu	$i,64($nap_d)
+	stdx	$t0,$rp,$i
+	stdx	$t1,$t6,$i
+	stdx	$i,$tp,$i	; zap tp at once
+	stdx	$i,$t4,$i
+	addi	$i,$i,16
+	bdnz-	Lcopy
+
+	$POP	r14,`2*$SIZE_T`($sp)
+	$POP	r15,`3*$SIZE_T`($sp)
+	$POP	r16,`4*$SIZE_T`($sp)
+	$POP	r17,`5*$SIZE_T`($sp)
+	$POP	r18,`6*$SIZE_T`($sp)
+	$POP	r19,`7*$SIZE_T`($sp)
+	$POP	r20,`8*$SIZE_T`($sp)
+	$POP	r21,`9*$SIZE_T`($sp)
+	$POP	r22,`10*$SIZE_T`($sp)
+	$POP	r23,`11*$SIZE_T`($sp)
+	lfd	f14,`12*$SIZE_T+0`($sp)
+	lfd	f15,`12*$SIZE_T+8`($sp)
+	lfd	f16,`12*$SIZE_T+16`($sp)
+	lfd	f17,`12*$SIZE_T+24`($sp)
+	lfd	f18,`12*$SIZE_T+32`($sp)
+	lfd	f19,`12*$SIZE_T+40`($sp)
+	lfd	f20,`12*$SIZE_T+48`($sp)
+	lfd	f21,`12*$SIZE_T+56`($sp)
+	lfd	f22,`12*$SIZE_T+64`($sp)
+	lfd	f23,`12*$SIZE_T+72`($sp)
+	lfd	f24,`12*$SIZE_T+80`($sp)
+	lfd	f25,`12*$SIZE_T+88`($sp)
+	$POP	$sp,0($sp)
+	li	r3,1	; signal "handled"
+	blr
+	.long	0
+.asciz  "Montgomery Multiplication for PPC64, CRYPTOGAMS by <appro\@fy.chalmers.se>"
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/crypto/bn/asm/s390x-mont.pl b/crypto/bn/asm/s390x-mont.pl
new file mode 100644
index 0000000..d232510
--- /dev/null
+++ b/crypto/bn/asm/s390x-mont.pl
@@ -0,0 +1,225 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# April 2007.
+#
+# Performance improvement over vanilla C code varies from 85% to 45%
+# depending on key length and benchmark. Unfortunately in this context
+# these are not very impressive results [for code that utilizes "wide"
+# 64x64=128-bit multiplication, which is not commonly available to C
+# programmers], at least hand-coded bn_asm.c replacement is known to
+# provide 30-40% better results for longest keys. Well, on a second
+# thought it's not very surprising, because z-CPUs are single-issue
+# and _strictly_ in-order execution, while bn_mul_mont is more or less
+# dependent on CPU ability to pipe-line instructions and have several
+# of them "in-flight" at the same time. I mean while other methods,
+# for example Karatsuba, aim to minimize amount of multiplications at
+# the cost of other operations increase, bn_mul_mont aim to neatly
+# "overlap" multiplications and the other operations [and on most
+# platforms even minimize the amount of the other operations, in
+# particular references to memory]. But it's possible to improve this
+# module performance by implementing dedicated squaring code-path and
+# possibly by unrolling loops...
+
+# January 2009.
+#
+# Reschedule to minimize/avoid Address Generation Interlock hazard,
+# make inner loops counter-based.
+
+$mn0="%r0";
+$num="%r1";
+
+# int bn_mul_mont(
+$rp="%r2";		# BN_ULONG *rp,
+$ap="%r3";		# const BN_ULONG *ap,
+$bp="%r4";		# const BN_ULONG *bp,
+$np="%r5";		# const BN_ULONG *np,
+$n0="%r6";		# const BN_ULONG *n0,
+#$num="160(%r15)"	# int num);
+
+$bi="%r2";	# zaps rp
+$j="%r7";
+
+$ahi="%r8";
+$alo="%r9";
+$nhi="%r10";
+$nlo="%r11";
+$AHI="%r12";
+$NHI="%r13";
+$count="%r14";
+$sp="%r15";
+
+$code.=<<___;
+.text
+.globl	bn_mul_mont
+.type	bn_mul_mont,\@function
+bn_mul_mont:
+	lgf	$num,164($sp)	# pull $num
+	sla	$num,3		# $num to enumerate bytes
+	la	$bp,0($num,$bp)
+
+	stg	%r2,16($sp)
+
+	cghi	$num,16		#
+	lghi	%r2,0		#
+	blr	%r14		# if($num<16) return 0;
+	cghi	$num,128	#
+	bhr	%r14		# if($num>128) return 0;
+
+	stmg	%r3,%r15,24($sp)
+
+	lghi	$rp,-160-8	# leave room for carry bit
+	lcgr	$j,$num		# -$num
+	lgr	%r0,$sp
+	la	$rp,0($rp,$sp)
+	la	$sp,0($j,$rp)	# alloca
+	stg	%r0,0($sp)	# back chain
+
+	sra	$num,3		# restore $num
+	la	$bp,0($j,$bp)	# restore $bp
+	ahi	$num,-1		# adjust $num for inner loop
+	lg	$n0,0($n0)	# pull n0
+
+	lg	$bi,0($bp)
+	lg	$alo,0($ap)
+	mlgr	$ahi,$bi	# ap[0]*bp[0]
+	lgr	$AHI,$ahi
+
+	lgr	$mn0,$alo	# "tp[0]"*n0
+	msgr	$mn0,$n0
+
+	lg	$nlo,0($np)	#
+	mlgr	$nhi,$mn0	# np[0]*m1
+	algr	$nlo,$alo	# +="tp[0]"
+	lghi	$NHI,0
+	alcgr	$NHI,$nhi
+
+	la	$j,8(%r0)	# j=1
+	lr	$count,$num
+
+.align	16
+.L1st:
+	lg	$alo,0($j,$ap)
+	mlgr	$ahi,$bi	# ap[j]*bp[0]
+	algr	$alo,$AHI
+	lghi	$AHI,0
+	alcgr	$AHI,$ahi
+
+	lg	$nlo,0($j,$np)
+	mlgr	$nhi,$mn0	# np[j]*m1
+	algr	$nlo,$NHI
+	lghi	$NHI,0
+	alcgr	$nhi,$NHI	# +="tp[j]"
+	algr	$nlo,$alo
+	alcgr	$NHI,$nhi
+
+	stg	$nlo,160-8($j,$sp)	# tp[j-1]=
+	la	$j,8($j)	# j++
+	brct	$count,.L1st
+
+	algr	$NHI,$AHI
+	lghi	$AHI,0
+	alcgr	$AHI,$AHI	# upmost overflow bit
+	stg	$NHI,160-8($j,$sp)
+	stg	$AHI,160($j,$sp)
+	la	$bp,8($bp)	# bp++
+
+.Louter:
+	lg	$bi,0($bp)	# bp[i]
+	lg	$alo,0($ap)
+	mlgr	$ahi,$bi	# ap[0]*bp[i]
+	alg	$alo,160($sp)	# +=tp[0]
+	lghi	$AHI,0
+	alcgr	$AHI,$ahi
+
+	lgr	$mn0,$alo
+	msgr	$mn0,$n0	# tp[0]*n0
+
+	lg	$nlo,0($np)	# np[0]
+	mlgr	$nhi,$mn0	# np[0]*m1
+	algr	$nlo,$alo	# +="tp[0]"
+	lghi	$NHI,0
+	alcgr	$NHI,$nhi
+
+	la	$j,8(%r0)	# j=1
+	lr	$count,$num
+
+.align	16
+.Linner:
+	lg	$alo,0($j,$ap)
+	mlgr	$ahi,$bi	# ap[j]*bp[i]
+	algr	$alo,$AHI
+	lghi	$AHI,0
+	alcgr	$ahi,$AHI
+	alg	$alo,160($j,$sp)# +=tp[j]
+	alcgr	$AHI,$ahi
+
+	lg	$nlo,0($j,$np)
+	mlgr	$nhi,$mn0	# np[j]*m1
+	algr	$nlo,$NHI
+	lghi	$NHI,0
+	alcgr	$nhi,$NHI
+	algr	$nlo,$alo	# +="tp[j]"
+	alcgr	$NHI,$nhi
+
+	stg	$nlo,160-8($j,$sp)	# tp[j-1]=
+	la	$j,8($j)	# j++
+	brct	$count,.Linner
+
+	algr	$NHI,$AHI
+	lghi	$AHI,0
+	alcgr	$AHI,$AHI
+	alg	$NHI,160($j,$sp)# accumulate previous upmost overflow bit
+	lghi	$ahi,0
+	alcgr	$AHI,$ahi	# new upmost overflow bit
+	stg	$NHI,160-8($j,$sp)
+	stg	$AHI,160($j,$sp)
+
+	la	$bp,8($bp)	# bp++
+	clg	$bp,160+8+32($j,$sp)	# compare to &bp[num]
+	jne	.Louter
+
+	lg	$rp,160+8+16($j,$sp)	# reincarnate rp
+	la	$ap,160($sp)
+	ahi	$num,1		# restore $num, incidentally clears "borrow"
+
+	la	$j,0(%r0)
+	lr	$count,$num
+.Lsub:	lg	$alo,0($j,$ap)
+	slbg	$alo,0($j,$np)
+	stg	$alo,0($j,$rp)
+	la	$j,8($j)
+	brct	$count,.Lsub
+	lghi	$ahi,0
+	slbgr	$AHI,$ahi	# handle upmost carry
+
+	ngr	$ap,$AHI
+	lghi	$np,-1
+	xgr	$np,$AHI
+	ngr	$np,$rp
+	ogr	$ap,$np		# ap=borrow?tp:rp
+
+	la	$j,0(%r0)
+	lgr	$count,$num
+.Lcopy:	lg	$alo,0($j,$ap)	# copy or in-place refresh
+	stg	$j,160($j,$sp)	# zap tp
+	stg	$alo,0($j,$rp)
+	la	$j,8($j)
+	brct	$count,.Lcopy
+
+	la	%r1,160+8+48($j,$sp)
+	lmg	%r6,%r15,0(%r1)
+	lghi	%r2,1		# signal "processed"
+	br	%r14
+.size	bn_mul_mont,.-bn_mul_mont
+.string	"Montgomery Multiplication for s390x, CRYPTOGAMS by <appro\@openssl.org>"
+___
+
+print $code;
+close STDOUT;
diff --git a/crypto/bn/asm/s390x.S b/crypto/bn/asm/s390x.S
new file mode 100755
index 0000000..8f45f5d
--- /dev/null
+++ b/crypto/bn/asm/s390x.S
@@ -0,0 +1,678 @@
+.ident "s390x.S, version 1.0"
+// ====================================================================
+// Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+// project.
+//
+// Rights for redistribution and usage in source and binary forms are
+// granted according to the OpenSSL license. Warranty of any kind is
+// disclaimed.
+// ====================================================================
+
+.text
+
+#define zero	%r0
+
+// BN_ULONG bn_mul_add_words(BN_ULONG *r2,BN_ULONG *r3,int r4,BN_ULONG r5);
+.globl	bn_mul_add_words
+.type	bn_mul_add_words,@function
+.align	4
+bn_mul_add_words:
+	lghi	zero,0		// zero = 0
+	la	%r1,0(%r2)	// put rp aside
+	lghi	%r2,0		// i=0;
+	ltgfr	%r4,%r4
+	bler	%r14		// if (len<=0) return 0;
+
+	stmg	%r6,%r10,48(%r15)
+	lghi	%r8,0		// carry = 0
+	srag	%r10,%r4,2	// cnt=len/4
+	jz	.Loop1_madd
+
+.Loop4_madd:
+	lg	%r7,0(%r2,%r3)	// ap[i]
+	mlgr	%r6,%r5		// *=w
+	algr	%r7,%r8		// +=carry
+	alcgr	%r6,zero
+	alg	%r7,0(%r2,%r1)	// +=rp[i]
+	alcgr	%r6,zero
+	stg	%r7,0(%r2,%r1)	// rp[i]=
+
+	lg	%r9,8(%r2,%r3)
+	mlgr	%r8,%r5
+	algr	%r9,%r6
+	alcgr	%r8,zero
+	alg	%r9,8(%r2,%r1)
+	alcgr	%r8,zero
+	stg	%r9,8(%r2,%r1)
+
+	lg	%r7,16(%r2,%r3)
+	mlgr	%r6,%r5
+	algr	%r7,%r8
+	alcgr	%r6,zero
+	alg	%r7,16(%r2,%r1)
+	alcgr	%r6,zero
+	stg	%r7,16(%r2,%r1)
+
+	lg	%r9,24(%r2,%r3)
+	mlgr	%r8,%r5
+	algr	%r9,%r6
+	alcgr	%r8,zero
+	alg	%r9,24(%r2,%r1)
+	alcgr	%r8,zero
+	stg	%r9,24(%r2,%r1)
+
+	la	%r2,32(%r2)	// i+=4
+	brct	%r10,.Loop4_madd
+
+	lghi	%r10,3
+	nr	%r4,%r10	// cnt=len%4
+	jz	.Lend_madd
+
+.Loop1_madd:
+	lg	%r7,0(%r2,%r3)	// ap[i]
+	mlgr	%r6,%r5		// *=w
+	algr	%r7,%r8		// +=carry
+	alcgr	%r6,zero
+	alg	%r7,0(%r2,%r1)	// +=rp[i]
+	alcgr	%r6,zero
+	stg	%r7,0(%r2,%r1)	// rp[i]=
+
+	lgr	%r8,%r6
+	la	%r2,8(%r2)	// i++
+	brct	%r4,.Loop1_madd
+
+.Lend_madd:
+	lgr	%r2,%r8
+	lmg	%r6,%r10,48(%r15)
+	br	%r14
+.size	bn_mul_add_words,.-bn_mul_add_words
+
+// BN_ULONG bn_mul_words(BN_ULONG *r2,BN_ULONG *r3,int r4,BN_ULONG r5);
+.globl	bn_mul_words
+.type	bn_mul_words,@function
+.align	4
+bn_mul_words:
+	lghi	zero,0		// zero = 0
+	la	%r1,0(%r2)	// put rp aside
+	lghi	%r2,0		// i=0;
+	ltgfr	%r4,%r4
+	bler	%r14		// if (len<=0) return 0;
+
+	stmg	%r6,%r10,48(%r15)
+	lghi	%r8,0		// carry = 0
+	srag	%r10,%r4,2	// cnt=len/4
+	jz	.Loop1_mul
+
+.Loop4_mul:
+	lg	%r7,0(%r2,%r3)	// ap[i]
+	mlgr	%r6,%r5		// *=w
+	algr	%r7,%r8		// +=carry
+	alcgr	%r6,zero
+	stg	%r7,0(%r2,%r1)	// rp[i]=
+
+	lg	%r9,8(%r2,%r3)
+	mlgr	%r8,%r5
+	algr	%r9,%r6
+	alcgr	%r8,zero
+	stg	%r9,8(%r2,%r1)
+
+	lg	%r7,16(%r2,%r3)
+	mlgr	%r6,%r5
+	algr	%r7,%r8
+	alcgr	%r6,zero
+	stg	%r7,16(%r2,%r1)
+
+	lg	%r9,24(%r2,%r3)
+	mlgr	%r8,%r5
+	algr	%r9,%r6
+	alcgr	%r8,zero
+	stg	%r9,24(%r2,%r1)
+
+	la	%r2,32(%r2)	// i+=4
+	brct	%r10,.Loop4_mul
+
+	lghi	%r10,3
+	nr	%r4,%r10	// cnt=len%4
+	jz	.Lend_mul
+
+.Loop1_mul:
+	lg	%r7,0(%r2,%r3)	// ap[i]
+	mlgr	%r6,%r5		// *=w
+	algr	%r7,%r8		// +=carry
+	alcgr	%r6,zero
+	stg	%r7,0(%r2,%r1)	// rp[i]=
+
+	lgr	%r8,%r6
+	la	%r2,8(%r2)	// i++
+	brct	%r4,.Loop1_mul
+
+.Lend_mul:
+	lgr	%r2,%r8
+	lmg	%r6,%r10,48(%r15)
+	br	%r14
+.size	bn_mul_words,.-bn_mul_words
+
+// void bn_sqr_words(BN_ULONG *r2,BN_ULONG *r2,int r4)
+.globl	bn_sqr_words
+.type	bn_sqr_words,@function
+.align	4
+bn_sqr_words:
+	ltgfr	%r4,%r4
+	bler	%r14
+
+	stmg	%r6,%r7,48(%r15)
+	srag	%r1,%r4,2	// cnt=len/4
+	jz	.Loop1_sqr
+
+.Loop4_sqr:
+	lg	%r7,0(%r3)
+	mlgr	%r6,%r7
+	stg	%r7,0(%r2)
+	stg	%r6,8(%r2)
+
+	lg	%r7,8(%r3)
+	mlgr	%r6,%r7
+	stg	%r7,16(%r2)
+	stg	%r6,24(%r2)
+
+	lg	%r7,16(%r3)
+	mlgr	%r6,%r7
+	stg	%r7,32(%r2)
+	stg	%r6,40(%r2)
+
+	lg	%r7,24(%r3)
+	mlgr	%r6,%r7
+	stg	%r7,48(%r2)
+	stg	%r6,56(%r2)
+
+	la	%r3,32(%r3)
+	la	%r2,64(%r2)
+	brct	%r1,.Loop4_sqr
+
+	lghi	%r1,3
+	nr	%r4,%r1		// cnt=len%4
+	jz	.Lend_sqr
+
+.Loop1_sqr:
+	lg	%r7,0(%r3)
+	mlgr	%r6,%r7
+	stg	%r7,0(%r2)
+	stg	%r6,8(%r2)
+
+	la	%r3,8(%r3)
+	la	%r2,16(%r2)
+	brct	%r4,.Loop1_sqr
+
+.Lend_sqr:
+	lmg	%r6,%r7,48(%r15)
+	br	%r14
+.size	bn_sqr_words,.-bn_sqr_words
+
+// BN_ULONG bn_div_words(BN_ULONG h,BN_ULONG l,BN_ULONG d);
+.globl	bn_div_words
+.type	bn_div_words,@function
+.align	4
+bn_div_words:
+	dlgr	%r2,%r4
+	lgr	%r2,%r3
+	br	%r14
+.size	bn_div_words,.-bn_div_words
+
+// BN_ULONG bn_add_words(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4,int r5);
+.globl	bn_add_words
+.type	bn_add_words,@function
+.align	4
+bn_add_words:
+	la	%r1,0(%r2)	// put rp aside
+	lghi	%r2,0		// i=0
+	ltgfr	%r5,%r5
+	bler	%r14		// if (len<=0) return 0;
+
+	stg	%r6,48(%r15)
+	lghi	%r6,3
+	nr	%r6,%r5		// len%4
+	sra	%r5,2		// len/4, use sra because it sets condition code
+	jz	.Loop1_add	// carry is incidentally cleared if branch taken
+	algr	%r2,%r2		// clear carry
+
+.Loop4_add:
+	lg	%r0,0(%r2,%r3)
+	alcg	%r0,0(%r2,%r4)
+	stg	%r0,0(%r2,%r1)
+	lg	%r0,8(%r2,%r3)
+	alcg	%r0,8(%r2,%r4)
+	stg	%r0,8(%r2,%r1)
+	lg	%r0,16(%r2,%r3)
+	alcg	%r0,16(%r2,%r4)
+	stg	%r0,16(%r2,%r1)
+	lg	%r0,24(%r2,%r3)
+	alcg	%r0,24(%r2,%r4)
+	stg	%r0,24(%r2,%r1)
+
+	la	%r2,32(%r2)	// i+=4
+	brct	%r5,.Loop4_add
+
+	la	%r6,1(%r6)	// see if len%4 is zero ...
+	brct	%r6,.Loop1_add	// without touching condition code:-)
+
+.Lexit_add:
+	lghi	%r2,0
+	alcgr	%r2,%r2
+	lg	%r6,48(%r15)
+	br	%r14
+
+.Loop1_add:
+	lg	%r0,0(%r2,%r3)
+	alcg	%r0,0(%r2,%r4)
+	stg	%r0,0(%r2,%r1)
+
+	la	%r2,8(%r2)	// i++
+	brct	%r6,.Loop1_add
+
+	j	.Lexit_add
+.size	bn_add_words,.-bn_add_words
+
+// BN_ULONG bn_sub_words(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4,int r5);
+.globl	bn_sub_words
+.type	bn_sub_words,@function
+.align	4
+bn_sub_words:
+	la	%r1,0(%r2)	// put rp aside
+	lghi	%r2,0		// i=0
+	ltgfr	%r5,%r5
+	bler	%r14		// if (len<=0) return 0;
+
+	stg	%r6,48(%r15)
+	lghi	%r6,3
+	nr	%r6,%r5		// len%4
+	sra	%r5,2		// len/4, use sra because it sets condition code
+	jnz	.Loop4_sub	// borrow is incidentally cleared if branch taken
+	slgr	%r2,%r2		// clear borrow
+
+.Loop1_sub:
+	lg	%r0,0(%r2,%r3)
+	slbg	%r0,0(%r2,%r4)
+	stg	%r0,0(%r2,%r1)
+
+	la	%r2,8(%r2)	// i++
+	brct	%r6,.Loop1_sub
+	j	.Lexit_sub
+
+.Loop4_sub:
+	lg	%r0,0(%r2,%r3)
+	slbg	%r0,0(%r2,%r4)
+	stg	%r0,0(%r2,%r1)
+	lg	%r0,8(%r2,%r3)
+	slbg	%r0,8(%r2,%r4)
+	stg	%r0,8(%r2,%r1)
+	lg	%r0,16(%r2,%r3)
+	slbg	%r0,16(%r2,%r4)
+	stg	%r0,16(%r2,%r1)
+	lg	%r0,24(%r2,%r3)
+	slbg	%r0,24(%r2,%r4)
+	stg	%r0,24(%r2,%r1)
+
+	la	%r2,32(%r2)	// i+=4
+	brct	%r5,.Loop4_sub
+
+	la	%r6,1(%r6)	// see if len%4 is zero ...
+	brct	%r6,.Loop1_sub	// without touching condition code:-)
+
+.Lexit_sub:
+	lghi	%r2,0
+	slbgr	%r2,%r2
+	lcgr	%r2,%r2
+	lg	%r6,48(%r15)
+	br	%r14
+.size	bn_sub_words,.-bn_sub_words
+
+#define c1	%r1
+#define c2	%r5
+#define c3	%r8
+
+#define mul_add_c(ai,bi,c1,c2,c3)	\
+	lg	%r7,ai*8(%r3);		\
+	mlg	%r6,bi*8(%r4);		\
+	algr	c1,%r7;			\
+	alcgr	c2,%r6;			\
+	alcgr	c3,zero
+
+// void bn_mul_comba8(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4);
+.globl	bn_mul_comba8
+.type	bn_mul_comba8,@function
+.align	4
+bn_mul_comba8:
+	stmg	%r6,%r8,48(%r15)
+
+	lghi	c1,0
+	lghi	c2,0
+	lghi	c3,0
+	lghi	zero,0
+
+	mul_add_c(0,0,c1,c2,c3);
+	stg	c1,0*8(%r2)
+	lghi	c1,0
+
+	mul_add_c(0,1,c2,c3,c1);
+	mul_add_c(1,0,c2,c3,c1);
+	stg	c2,1*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(2,0,c3,c1,c2);
+	mul_add_c(1,1,c3,c1,c2);
+	mul_add_c(0,2,c3,c1,c2);
+	stg	c3,2*8(%r2)
+	lghi	c3,0
+
+	mul_add_c(0,3,c1,c2,c3);
+	mul_add_c(1,2,c1,c2,c3);
+	mul_add_c(2,1,c1,c2,c3);
+	mul_add_c(3,0,c1,c2,c3);
+	stg	c1,3*8(%r2)
+	lghi	c1,0
+
+	mul_add_c(4,0,c2,c3,c1);
+	mul_add_c(3,1,c2,c3,c1);
+	mul_add_c(2,2,c2,c3,c1);
+	mul_add_c(1,3,c2,c3,c1);
+	mul_add_c(0,4,c2,c3,c1);
+	stg	c2,4*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(0,5,c3,c1,c2);
+	mul_add_c(1,4,c3,c1,c2);
+	mul_add_c(2,3,c3,c1,c2);
+	mul_add_c(3,2,c3,c1,c2);
+	mul_add_c(4,1,c3,c1,c2);
+	mul_add_c(5,0,c3,c1,c2);
+	stg	c3,5*8(%r2)
+	lghi	c3,0
+
+	mul_add_c(6,0,c1,c2,c3);
+	mul_add_c(5,1,c1,c2,c3);
+	mul_add_c(4,2,c1,c2,c3);
+	mul_add_c(3,3,c1,c2,c3);
+	mul_add_c(2,4,c1,c2,c3);
+	mul_add_c(1,5,c1,c2,c3);
+	mul_add_c(0,6,c1,c2,c3);
+	stg	c1,6*8(%r2)
+	lghi	c1,0
+
+	mul_add_c(0,7,c2,c3,c1);
+	mul_add_c(1,6,c2,c3,c1);
+	mul_add_c(2,5,c2,c3,c1);
+	mul_add_c(3,4,c2,c3,c1);
+	mul_add_c(4,3,c2,c3,c1);
+	mul_add_c(5,2,c2,c3,c1);
+	mul_add_c(6,1,c2,c3,c1);
+	mul_add_c(7,0,c2,c3,c1);
+	stg	c2,7*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(7,1,c3,c1,c2);
+	mul_add_c(6,2,c3,c1,c2);
+	mul_add_c(5,3,c3,c1,c2);
+	mul_add_c(4,4,c3,c1,c2);
+	mul_add_c(3,5,c3,c1,c2);
+	mul_add_c(2,6,c3,c1,c2);
+	mul_add_c(1,7,c3,c1,c2);
+	stg	c3,8*8(%r2)
+	lghi	c3,0
+
+	mul_add_c(2,7,c1,c2,c3);
+	mul_add_c(3,6,c1,c2,c3);
+	mul_add_c(4,5,c1,c2,c3);
+	mul_add_c(5,4,c1,c2,c3);
+	mul_add_c(6,3,c1,c2,c3);
+	mul_add_c(7,2,c1,c2,c3);
+	stg	c1,9*8(%r2)
+	lghi	c1,0
+
+	mul_add_c(7,3,c2,c3,c1);
+	mul_add_c(6,4,c2,c3,c1);
+	mul_add_c(5,5,c2,c3,c1);
+	mul_add_c(4,6,c2,c3,c1);
+	mul_add_c(3,7,c2,c3,c1);
+	stg	c2,10*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(4,7,c3,c1,c2);
+	mul_add_c(5,6,c3,c1,c2);
+	mul_add_c(6,5,c3,c1,c2);
+	mul_add_c(7,4,c3,c1,c2);
+	stg	c3,11*8(%r2)
+	lghi	c3,0
+
+	mul_add_c(7,5,c1,c2,c3);
+	mul_add_c(6,6,c1,c2,c3);
+	mul_add_c(5,7,c1,c2,c3);
+	stg	c1,12*8(%r2)
+	lghi	c1,0
+
+
+	mul_add_c(6,7,c2,c3,c1);
+	mul_add_c(7,6,c2,c3,c1);
+	stg	c2,13*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(7,7,c3,c1,c2);
+	stg	c3,14*8(%r2)
+	stg	c1,15*8(%r2)
+
+	lmg	%r6,%r8,48(%r15)
+	br	%r14
+.size	bn_mul_comba8,.-bn_mul_comba8
+
+// void bn_mul_comba4(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4);
+.globl	bn_mul_comba4
+.type	bn_mul_comba4,@function
+.align	4
+bn_mul_comba4:
+	stmg	%r6,%r8,48(%r15)
+
+	lghi	c1,0
+	lghi	c2,0
+	lghi	c3,0
+	lghi	zero,0
+
+	mul_add_c(0,0,c1,c2,c3);
+	stg	c1,0*8(%r3)
+	lghi	c1,0
+
+	mul_add_c(0,1,c2,c3,c1);
+	mul_add_c(1,0,c2,c3,c1);
+	stg	c2,1*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(2,0,c3,c1,c2);
+	mul_add_c(1,1,c3,c1,c2);
+	mul_add_c(0,2,c3,c1,c2);
+	stg	c3,2*8(%r2)
+	lghi	c3,0
+
+	mul_add_c(0,3,c1,c2,c3);
+	mul_add_c(1,2,c1,c2,c3);
+	mul_add_c(2,1,c1,c2,c3);
+	mul_add_c(3,0,c1,c2,c3);
+	stg	c1,3*8(%r2)
+	lghi	c1,0
+
+	mul_add_c(3,1,c2,c3,c1);
+	mul_add_c(2,2,c2,c3,c1);
+	mul_add_c(1,3,c2,c3,c1);
+	stg	c2,4*8(%r2)
+	lghi	c2,0
+
+	mul_add_c(2,3,c3,c1,c2);
+	mul_add_c(3,2,c3,c1,c2);
+	stg	c3,5*8(%r2)
+	lghi	c3,0
+
+	mul_add_c(3,3,c1,c2,c3);
+	stg	c1,6*8(%r2)
+	stg	c2,7*8(%r2)
+
+	stmg	%r6,%r8,48(%r15)
+	br	%r14
+.size	bn_mul_comba4,.-bn_mul_comba4
+
+#define sqr_add_c(ai,c1,c2,c3)		\
+	lg	%r7,ai*8(%r3);		\
+	mlgr	%r6,%r7;		\
+	algr	c1,%r7;			\
+	alcgr	c2,%r6;			\
+	alcgr	c3,zero
+
+#define sqr_add_c2(ai,aj,c1,c2,c3)	\
+	lg	%r7,ai*8(%r3);		\
+	mlg	%r6,aj*8(%r3);		\
+	algr	c1,%r7;			\
+	alcgr	c2,%r6;			\
+	alcgr	c3,zero;		\
+	algr	c1,%r7;			\
+	alcgr	c2,%r6;			\
+	alcgr	c3,zero
+
+// void bn_sqr_comba8(BN_ULONG *r2,BN_ULONG *r3);
+.globl	bn_sqr_comba8
+.type	bn_sqr_comba8,@function
+.align	4
+bn_sqr_comba8:
+	stmg	%r6,%r8,48(%r15)
+
+	lghi	c1,0
+	lghi	c2,0
+	lghi	c3,0
+	lghi	zero,0
+
+	sqr_add_c(0,c1,c2,c3);
+	stg	c1,0*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c2(1,0,c2,c3,c1);
+	stg	c2,1*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c(1,c3,c1,c2);
+	sqr_add_c2(2,0,c3,c1,c2);
+	stg	c3,2*8(%r2)
+	lghi	c3,0
+
+	sqr_add_c2(3,0,c1,c2,c3);
+	sqr_add_c2(2,1,c1,c2,c3);
+	stg	c1,3*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c(2,c2,c3,c1);
+	sqr_add_c2(3,1,c2,c3,c1);
+	sqr_add_c2(4,0,c2,c3,c1);
+	stg	c2,4*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c2(5,0,c3,c1,c2);
+	sqr_add_c2(4,1,c3,c1,c2);
+	sqr_add_c2(3,2,c3,c1,c2);
+	stg	c3,5*8(%r2)
+	lghi	c3,0
+
+	sqr_add_c(3,c1,c2,c3);
+	sqr_add_c2(4,2,c1,c2,c3);
+	sqr_add_c2(5,1,c1,c2,c3);
+	sqr_add_c2(6,0,c1,c2,c3);
+	stg	c1,6*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c2(7,0,c2,c3,c1);
+	sqr_add_c2(6,1,c2,c3,c1);
+	sqr_add_c2(5,2,c2,c3,c1);
+	sqr_add_c2(4,3,c2,c3,c1);
+	stg	c2,7*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c(4,c3,c1,c2);
+	sqr_add_c2(5,3,c3,c1,c2);
+	sqr_add_c2(6,2,c3,c1,c2);
+	sqr_add_c2(7,1,c3,c1,c2);
+	stg	c3,8*8(%r2)
+	lghi	c3,0
+
+	sqr_add_c2(7,2,c1,c2,c3);
+	sqr_add_c2(6,3,c1,c2,c3);
+	sqr_add_c2(5,4,c1,c2,c3);
+	stg	c1,9*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c(5,c2,c3,c1);
+	sqr_add_c2(6,4,c2,c3,c1);
+	sqr_add_c2(7,3,c2,c3,c1);
+	stg	c2,10*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c2(7,4,c3,c1,c2);
+	sqr_add_c2(6,5,c3,c1,c2);
+	stg	c3,11*8(%r2)
+	lghi	c3,0
+
+	sqr_add_c(6,c1,c2,c3);
+	sqr_add_c2(7,5,c1,c2,c3);
+	stg	c1,12*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c2(7,6,c2,c3,c1);
+	stg	c2,13*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c(7,c3,c1,c2);
+	stg	c3,14*8(%r2)
+	stg	c1,15*8(%r2)
+
+	lmg	%r6,%r8,48(%r15)
+	br	%r14
+.size	bn_sqr_comba8,.-bn_sqr_comba8
+
+// void bn_sqr_comba4(BN_ULONG *r2,BN_ULONG *r3);
+.globl bn_sqr_comba4
+.type	bn_sqr_comba4,@function
+.align	4
+bn_sqr_comba4:
+	stmg	%r6,%r8,48(%r15)
+
+	lghi	c1,0
+	lghi	c2,0
+	lghi	c3,0
+	lghi	zero,0
+
+	sqr_add_c(0,c1,c2,c3);
+	stg	c1,0*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c2(1,0,c2,c3,c1);
+	stg	c2,1*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c(1,c3,c1,c2);
+	sqr_add_c2(2,0,c3,c1,c2);
+	stg	c3,2*8(%r2)
+	lghi	c3,0
+
+	sqr_add_c2(3,0,c1,c2,c3);
+	sqr_add_c2(2,1,c1,c2,c3);
+	stg	c1,3*8(%r2)
+	lghi	c1,0
+
+	sqr_add_c(2,c2,c3,c1);
+	sqr_add_c2(3,1,c2,c3,c1);
+	stg	c2,4*8(%r2)
+	lghi	c2,0
+
+	sqr_add_c2(3,2,c3,c1,c2);
+	stg	c3,5*8(%r2)
+	lghi	c3,0
+
+	sqr_add_c(3,c1,c2,c3);
+	stg	c1,6*8(%r2)
+	stg	c2,7*8(%r2)
+
+	lmg	%r6,%r8,48(%r15)
+	br	%r14
+.size	bn_sqr_comba4,.-bn_sqr_comba4
diff --git a/crypto/bn/asm/sparcv9-mont.pl b/crypto/bn/asm/sparcv9-mont.pl
new file mode 100644
index 0000000..b8fb1e8
--- /dev/null
+++ b/crypto/bn/asm/sparcv9-mont.pl
@@ -0,0 +1,606 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# December 2005
+#
+# Pure SPARCv9/8+ and IALU-only bn_mul_mont implementation. The reasons
+# for undertaken effort are multiple. First of all, UltraSPARC is not
+# the whole SPARCv9 universe and other VIS-free implementations deserve
+# optimized code as much. Secondly, newly introduced UltraSPARC T1,
+# a.k.a. Niagara, has shared FPU and concurrent FPU-intensive pathes,
+# such as sparcv9a-mont, will simply sink it. Yes, T1 is equipped with
+# several integrated RSA/DSA accelerator circuits accessible through
+# kernel driver [only(*)], but having decent user-land software
+# implementation is important too. Finally, reasons like desire to
+# experiment with dedicated squaring procedure. Yes, this module
+# implements one, because it was easiest to draft it in SPARCv9
+# instructions...
+
+# (*)	Engine accessing the driver in question is on my TODO list.
+#	For reference, acceleator is estimated to give 6 to 10 times
+#	improvement on single-threaded RSA sign. It should be noted
+#	that 6-10x improvement coefficient does not actually mean
+#	something extraordinary in terms of absolute [single-threaded]
+#	performance, as SPARCv9 instruction set is by all means least
+#	suitable for high performance crypto among other 64 bit
+#	platforms. 6-10x factor simply places T1 in same performance
+#	domain as say AMD64 and IA-64. Improvement of RSA verify don't
+#	appear impressive at all, but it's the sign operation which is
+#	far more critical/interesting.
+
+# You might notice that inner loops are modulo-scheduled:-) This has
+# essentially negligible impact on UltraSPARC performance, it's
+# Fujitsu SPARC64 V users who should notice and hopefully appreciate
+# the advantage... Currently this module surpasses sparcv9a-mont.pl
+# by ~20% on UltraSPARC-III and later cores, but recall that sparcv9a
+# module still have hidden potential [see TODO list there], which is
+# estimated to be larger than 20%...
+
+# int bn_mul_mont(
+$rp="%i0";	# BN_ULONG *rp,
+$ap="%i1";	# const BN_ULONG *ap,
+$bp="%i2";	# const BN_ULONG *bp,
+$np="%i3";	# const BN_ULONG *np,
+$n0="%i4";	# const BN_ULONG *n0,
+$num="%i5";	# int num);
+
+$bits=32;
+for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
+if ($bits==64)	{ $bias=2047; $frame=192; }
+else		{ $bias=0;    $frame=128; }
+
+$car0="%o0";
+$car1="%o1";
+$car2="%o2";	# 1 bit
+$acc0="%o3";
+$acc1="%o4";
+$mask="%g1";	# 32 bits, what a waste...
+$tmp0="%g4";
+$tmp1="%g5";
+
+$i="%l0";
+$j="%l1";
+$mul0="%l2";
+$mul1="%l3";
+$tp="%l4";
+$apj="%l5";
+$npj="%l6";
+$tpj="%l7";
+
+$fname="bn_mul_mont_int";
+
+$code=<<___;
+.section	".text",#alloc,#execinstr
+
+.global	$fname
+.align	32
+$fname:
+	cmp	%o5,4			! 128 bits minimum
+	bge,pt	%icc,.Lenter
+	sethi	%hi(0xffffffff),$mask
+	retl
+	clr	%o0
+.align	32
+.Lenter:
+	save	%sp,-$frame,%sp
+	sll	$num,2,$num		! num*=4
+	or	$mask,%lo(0xffffffff),$mask
+	ld	[$n0],$n0
+	cmp	$ap,$bp
+	and	$num,$mask,$num
+	ld	[$bp],$mul0		! bp[0]
+	nop
+
+	add	%sp,$bias,%o7		! real top of stack
+	ld	[$ap],$car0		! ap[0] ! redundant in squaring context
+	sub	%o7,$num,%o7
+	ld	[$ap+4],$apj		! ap[1]
+	and	%o7,-1024,%o7
+	ld	[$np],$car1		! np[0]
+	sub	%o7,$bias,%sp		! alloca
+	ld	[$np+4],$npj		! np[1]
+	be,pt	`$bits==32?"%icc":"%xcc"`,.Lbn_sqr_mont
+	mov	12,$j
+
+	mulx	$car0,$mul0,$car0	! ap[0]*bp[0]
+	mulx	$apj,$mul0,$tmp0	!prologue! ap[1]*bp[0]
+	and	$car0,$mask,$acc0
+	add	%sp,$bias+$frame,$tp
+	ld	[$ap+8],$apj		!prologue!
+
+	mulx	$n0,$acc0,$mul1		! "t[0]"*n0
+	and	$mul1,$mask,$mul1
+
+	mulx	$car1,$mul1,$car1	! np[0]*"t[0]"*n0
+	mulx	$npj,$mul1,$acc1	!prologue! np[1]*"t[0]"*n0
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	ld	[$np+8],$npj		!prologue!
+	srlx	$car1,32,$car1
+	mov	$tmp0,$acc0		!prologue!
+
+.L1st:
+	mulx	$apj,$mul0,$tmp0
+	mulx	$npj,$mul1,$tmp1
+	add	$acc0,$car0,$car0
+	ld	[$ap+$j],$apj		! ap[j]
+	and	$car0,$mask,$acc0
+	add	$acc1,$car1,$car1
+	ld	[$np+$j],$npj		! np[j]
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	add	$j,4,$j			! j++
+	mov	$tmp0,$acc0
+	st	$car1,[$tp]
+	cmp	$j,$num
+	mov	$tmp1,$acc1
+	srlx	$car1,32,$car1
+	bl	%icc,.L1st
+	add	$tp,4,$tp		! tp++
+!.L1st
+
+	mulx	$apj,$mul0,$tmp0	!epilogue!
+	mulx	$npj,$mul1,$tmp1
+	add	$acc0,$car0,$car0
+	and	$car0,$mask,$acc0
+	add	$acc1,$car1,$car1
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp]
+	srlx	$car1,32,$car1
+
+	add	$tmp0,$car0,$car0
+	and	$car0,$mask,$acc0
+	add	$tmp1,$car1,$car1
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp+4]
+	srlx	$car1,32,$car1
+
+	add	$car0,$car1,$car1
+	st	$car1,[$tp+8]
+	srlx	$car1,32,$car2
+
+	mov	4,$i			! i++
+	ld	[$bp+4],$mul0		! bp[1]
+.Louter:
+	add	%sp,$bias+$frame,$tp
+	ld	[$ap],$car0		! ap[0]
+	ld	[$ap+4],$apj		! ap[1]
+	ld	[$np],$car1		! np[0]
+	ld	[$np+4],$npj		! np[1]
+	ld	[$tp],$tmp1		! tp[0]
+	ld	[$tp+4],$tpj		! tp[1]
+	mov	12,$j
+
+	mulx	$car0,$mul0,$car0
+	mulx	$apj,$mul0,$tmp0	!prologue!
+	add	$tmp1,$car0,$car0
+	ld	[$ap+8],$apj		!prologue!
+	and	$car0,$mask,$acc0
+
+	mulx	$n0,$acc0,$mul1
+	and	$mul1,$mask,$mul1
+
+	mulx	$car1,$mul1,$car1
+	mulx	$npj,$mul1,$acc1	!prologue!
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	ld	[$np+8],$npj		!prologue!
+	srlx	$car1,32,$car1
+	mov	$tmp0,$acc0		!prologue!
+
+.Linner:
+	mulx	$apj,$mul0,$tmp0
+	mulx	$npj,$mul1,$tmp1
+	add	$tpj,$car0,$car0
+	ld	[$ap+$j],$apj		! ap[j]
+	add	$acc0,$car0,$car0
+	add	$acc1,$car1,$car1
+	ld	[$np+$j],$npj		! np[j]
+	and	$car0,$mask,$acc0
+	ld	[$tp+8],$tpj		! tp[j]
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	add	$j,4,$j			! j++
+	mov	$tmp0,$acc0
+	st	$car1,[$tp]		! tp[j-1]
+	srlx	$car1,32,$car1
+	mov	$tmp1,$acc1
+	cmp	$j,$num
+	bl	%icc,.Linner
+	add	$tp,4,$tp		! tp++
+!.Linner
+
+	mulx	$apj,$mul0,$tmp0	!epilogue!
+	mulx	$npj,$mul1,$tmp1
+	add	$tpj,$car0,$car0
+	add	$acc0,$car0,$car0
+	ld	[$tp+8],$tpj		! tp[j]
+	and	$car0,$mask,$acc0
+	add	$acc1,$car1,$car1
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp]		! tp[j-1]
+	srlx	$car1,32,$car1
+
+	add	$tpj,$car0,$car0
+	add	$tmp0,$car0,$car0
+	and	$car0,$mask,$acc0
+	add	$tmp1,$car1,$car1
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp+4]		! tp[j-1]
+	srlx	$car0,32,$car0
+	add	$i,4,$i			! i++
+	srlx	$car1,32,$car1
+
+	add	$car0,$car1,$car1
+	cmp	$i,$num
+	add	$car2,$car1,$car1
+	st	$car1,[$tp+8]
+
+	srlx	$car1,32,$car2
+	bl,a	%icc,.Louter
+	ld	[$bp+$i],$mul0		! bp[i]
+!.Louter
+
+	add	$tp,12,$tp
+
+.Ltail:
+	add	$np,$num,$np
+	add	$rp,$num,$rp
+	mov	$tp,$ap
+	sub	%g0,$num,%o7		! k=-num
+	ba	.Lsub
+	subcc	%g0,%g0,%g0		! clear %icc.c
+.align	16
+.Lsub:
+	ld	[$tp+%o7],%o0
+	ld	[$np+%o7],%o1
+	subccc	%o0,%o1,%o1		! tp[j]-np[j]
+	add	$rp,%o7,$i
+	add	%o7,4,%o7
+	brnz	%o7,.Lsub
+	st	%o1,[$i]
+	subc	$car2,0,$car2		! handle upmost overflow bit
+	and	$tp,$car2,$ap
+	andn	$rp,$car2,$np
+	or	$ap,$np,$ap
+	sub	%g0,$num,%o7
+
+.Lcopy:
+	ld	[$ap+%o7],%o0		! copy or in-place refresh
+	st	%g0,[$tp+%o7]		! zap tp
+	st	%o0,[$rp+%o7]
+	add	%o7,4,%o7
+	brnz	%o7,.Lcopy
+	nop
+	mov	1,%i0
+	ret
+	restore
+___
+
+########
+######## .Lbn_sqr_mont gives up to 20% *overall* improvement over
+######## code without following dedicated squaring procedure.
+########
+$sbit="%i2";		# re-use $bp!
+
+$code.=<<___;
+.align	32
+.Lbn_sqr_mont:
+	mulx	$mul0,$mul0,$car0		! ap[0]*ap[0]
+	mulx	$apj,$mul0,$tmp0		!prologue!
+	and	$car0,$mask,$acc0
+	add	%sp,$bias+$frame,$tp
+	ld	[$ap+8],$apj			!prologue!
+
+	mulx	$n0,$acc0,$mul1			! "t[0]"*n0
+	srlx	$car0,32,$car0
+	and	$mul1,$mask,$mul1
+
+	mulx	$car1,$mul1,$car1		! np[0]*"t[0]"*n0
+	mulx	$npj,$mul1,$acc1		!prologue!
+	and	$car0,1,$sbit
+	ld	[$np+8],$npj			!prologue!
+	srlx	$car0,1,$car0
+	add	$acc0,$car1,$car1
+	srlx	$car1,32,$car1
+	mov	$tmp0,$acc0			!prologue!
+
+.Lsqr_1st:
+	mulx	$apj,$mul0,$tmp0
+	mulx	$npj,$mul1,$tmp1
+	add	$acc0,$car0,$car0		! ap[j]*a0+c0
+	add	$acc1,$car1,$car1
+	ld	[$ap+$j],$apj			! ap[j]
+	and	$car0,$mask,$acc0
+	ld	[$np+$j],$npj			! np[j]
+	srlx	$car0,32,$car0
+	add	$acc0,$acc0,$acc0
+	or	$sbit,$acc0,$acc0
+	mov	$tmp1,$acc1
+	srlx	$acc0,32,$sbit
+	add	$j,4,$j				! j++
+	and	$acc0,$mask,$acc0
+	cmp	$j,$num
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp]
+	mov	$tmp0,$acc0
+	srlx	$car1,32,$car1
+	bl	%icc,.Lsqr_1st
+	add	$tp,4,$tp			! tp++
+!.Lsqr_1st
+
+	mulx	$apj,$mul0,$tmp0		! epilogue
+	mulx	$npj,$mul1,$tmp1
+	add	$acc0,$car0,$car0		! ap[j]*a0+c0
+	add	$acc1,$car1,$car1
+	and	$car0,$mask,$acc0
+	srlx	$car0,32,$car0
+	add	$acc0,$acc0,$acc0
+	or	$sbit,$acc0,$acc0
+	srlx	$acc0,32,$sbit
+	and	$acc0,$mask,$acc0
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp]
+	srlx	$car1,32,$car1
+
+	add	$tmp0,$car0,$car0		! ap[j]*a0+c0
+	add	$tmp1,$car1,$car1
+	and	$car0,$mask,$acc0
+	srlx	$car0,32,$car0
+	add	$acc0,$acc0,$acc0
+	or	$sbit,$acc0,$acc0
+	srlx	$acc0,32,$sbit
+	and	$acc0,$mask,$acc0
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp+4]
+	srlx	$car1,32,$car1
+
+	add	$car0,$car0,$car0
+	or	$sbit,$car0,$car0
+	add	$car0,$car1,$car1
+	st	$car1,[$tp+8]
+	srlx	$car1,32,$car2
+
+	ld	[%sp+$bias+$frame],$tmp0	! tp[0]
+	ld	[%sp+$bias+$frame+4],$tmp1	! tp[1]
+	ld	[%sp+$bias+$frame+8],$tpj	! tp[2]
+	ld	[$ap+4],$mul0			! ap[1]
+	ld	[$ap+8],$apj			! ap[2]
+	ld	[$np],$car1			! np[0]
+	ld	[$np+4],$npj			! np[1]
+	mulx	$n0,$tmp0,$mul1
+
+	mulx	$mul0,$mul0,$car0
+	and	$mul1,$mask,$mul1
+
+	mulx	$car1,$mul1,$car1
+	mulx	$npj,$mul1,$acc1
+	add	$tmp0,$car1,$car1
+	and	$car0,$mask,$acc0
+	ld	[$np+8],$npj			! np[2]
+	srlx	$car1,32,$car1
+	add	$tmp1,$car1,$car1
+	srlx	$car0,32,$car0
+	add	$acc0,$car1,$car1
+	and	$car0,1,$sbit
+	add	$acc1,$car1,$car1
+	srlx	$car0,1,$car0
+	mov	12,$j
+	st	$car1,[%sp+$bias+$frame]	! tp[0]=
+	srlx	$car1,32,$car1
+	add	%sp,$bias+$frame+4,$tp
+
+.Lsqr_2nd:
+	mulx	$apj,$mul0,$acc0
+	mulx	$npj,$mul1,$acc1
+	add	$acc0,$car0,$car0
+	add	$tpj,$car1,$car1
+	ld	[$ap+$j],$apj			! ap[j]
+	and	$car0,$mask,$acc0
+	ld	[$np+$j],$npj			! np[j]
+	srlx	$car0,32,$car0
+	add	$acc1,$car1,$car1
+	ld	[$tp+8],$tpj			! tp[j]
+	add	$acc0,$acc0,$acc0
+	add	$j,4,$j				! j++
+	or	$sbit,$acc0,$acc0
+	srlx	$acc0,32,$sbit
+	and	$acc0,$mask,$acc0
+	cmp	$j,$num
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp]			! tp[j-1]
+	srlx	$car1,32,$car1
+	bl	%icc,.Lsqr_2nd
+	add	$tp,4,$tp			! tp++
+!.Lsqr_2nd
+
+	mulx	$apj,$mul0,$acc0
+	mulx	$npj,$mul1,$acc1
+	add	$acc0,$car0,$car0
+	add	$tpj,$car1,$car1
+	and	$car0,$mask,$acc0
+	srlx	$car0,32,$car0
+	add	$acc1,$car1,$car1
+	add	$acc0,$acc0,$acc0
+	or	$sbit,$acc0,$acc0
+	srlx	$acc0,32,$sbit
+	and	$acc0,$mask,$acc0
+	add	$acc0,$car1,$car1
+	st	$car1,[$tp]			! tp[j-1]
+	srlx	$car1,32,$car1
+
+	add	$car0,$car0,$car0
+	or	$sbit,$car0,$car0
+	add	$car0,$car1,$car1
+	add	$car2,$car1,$car1
+	st	$car1,[$tp+4]
+	srlx	$car1,32,$car2
+
+	ld	[%sp+$bias+$frame],$tmp1	! tp[0]
+	ld	[%sp+$bias+$frame+4],$tpj	! tp[1]
+	ld	[$ap+8],$mul0			! ap[2]
+	ld	[$np],$car1			! np[0]
+	ld	[$np+4],$npj			! np[1]
+	mulx	$n0,$tmp1,$mul1
+	and	$mul1,$mask,$mul1
+	mov	8,$i
+
+	mulx	$mul0,$mul0,$car0
+	mulx	$car1,$mul1,$car1
+	and	$car0,$mask,$acc0
+	add	$tmp1,$car1,$car1
+	srlx	$car0,32,$car0
+	add	%sp,$bias+$frame,$tp
+	srlx	$car1,32,$car1
+	and	$car0,1,$sbit
+	srlx	$car0,1,$car0
+	mov	4,$j
+
+.Lsqr_outer:
+.Lsqr_inner1:
+	mulx	$npj,$mul1,$acc1
+	add	$tpj,$car1,$car1
+	add	$j,4,$j
+	ld	[$tp+8],$tpj
+	cmp	$j,$i
+	add	$acc1,$car1,$car1
+	ld	[$np+$j],$npj
+	st	$car1,[$tp]
+	srlx	$car1,32,$car1
+	bl	%icc,.Lsqr_inner1
+	add	$tp,4,$tp
+!.Lsqr_inner1
+
+	add	$j,4,$j
+	ld	[$ap+$j],$apj			! ap[j]
+	mulx	$npj,$mul1,$acc1
+	add	$tpj,$car1,$car1
+	ld	[$np+$j],$npj			! np[j]
+	add	$acc0,$car1,$car1
+	ld	[$tp+8],$tpj			! tp[j]
+	add	$acc1,$car1,$car1
+	st	$car1,[$tp]
+	srlx	$car1,32,$car1
+
+	add	$j,4,$j
+	cmp	$j,$num
+	be,pn	%icc,.Lsqr_no_inner2
+	add	$tp,4,$tp
+
+.Lsqr_inner2:
+	mulx	$apj,$mul0,$acc0
+	mulx	$npj,$mul1,$acc1
+	add	$tpj,$car1,$car1
+	add	$acc0,$car0,$car0
+	ld	[$ap+$j],$apj			! ap[j]
+	and	$car0,$mask,$acc0
+	ld	[$np+$j],$npj			! np[j]
+	srlx	$car0,32,$car0
+	add	$acc0,$acc0,$acc0
+	ld	[$tp+8],$tpj			! tp[j]
+	or	$sbit,$acc0,$acc0
+	add	$j,4,$j				! j++
+	srlx	$acc0,32,$sbit
+	and	$acc0,$mask,$acc0
+	cmp	$j,$num
+	add	$acc0,$car1,$car1
+	add	$acc1,$car1,$car1
+	st	$car1,[$tp]			! tp[j-1]
+	srlx	$car1,32,$car1
+	bl	%icc,.Lsqr_inner2
+	add	$tp,4,$tp			! tp++
+
+.Lsqr_no_inner2:
+	mulx	$apj,$mul0,$acc0
+	mulx	$npj,$mul1,$acc1
+	add	$tpj,$car1,$car1
+	add	$acc0,$car0,$car0
+	and	$car0,$mask,$acc0
+	srlx	$car0,32,$car0
+	add	$acc0,$acc0,$acc0
+	or	$sbit,$acc0,$acc0
+	srlx	$acc0,32,$sbit
+	and	$acc0,$mask,$acc0
+	add	$acc0,$car1,$car1
+	add	$acc1,$car1,$car1
+	st	$car1,[$tp]			! tp[j-1]
+	srlx	$car1,32,$car1
+
+	add	$car0,$car0,$car0
+	or	$sbit,$car0,$car0
+	add	$car0,$car1,$car1
+	add	$car2,$car1,$car1
+	st	$car1,[$tp+4]
+	srlx	$car1,32,$car2
+
+	add	$i,4,$i				! i++
+	ld	[%sp+$bias+$frame],$tmp1	! tp[0]
+	ld	[%sp+$bias+$frame+4],$tpj	! tp[1]
+	ld	[$ap+$i],$mul0			! ap[j]
+	ld	[$np],$car1			! np[0]
+	ld	[$np+4],$npj			! np[1]
+	mulx	$n0,$tmp1,$mul1
+	and	$mul1,$mask,$mul1
+	add	$i,4,$tmp0
+
+	mulx	$mul0,$mul0,$car0
+	mulx	$car1,$mul1,$car1
+	and	$car0,$mask,$acc0
+	add	$tmp1,$car1,$car1
+	srlx	$car0,32,$car0
+	add	%sp,$bias+$frame,$tp
+	srlx	$car1,32,$car1
+	and	$car0,1,$sbit
+	srlx	$car0,1,$car0
+
+	cmp	$tmp0,$num			! i<num-1
+	bl	%icc,.Lsqr_outer
+	mov	4,$j
+
+.Lsqr_last:
+	mulx	$npj,$mul1,$acc1
+	add	$tpj,$car1,$car1
+	add	$j,4,$j
+	ld	[$tp+8],$tpj
+	cmp	$j,$i
+	add	$acc1,$car1,$car1
+	ld	[$np+$j],$npj
+	st	$car1,[$tp]
+	srlx	$car1,32,$car1
+	bl	%icc,.Lsqr_last
+	add	$tp,4,$tp
+!.Lsqr_last
+
+	mulx	$npj,$mul1,$acc1
+	add	$tpj,$car1,$car1
+	add	$acc0,$car1,$car1
+	add	$acc1,$car1,$car1
+	st	$car1,[$tp]
+	srlx	$car1,32,$car1
+
+	add	$car0,$car0,$car0		! recover $car0
+	or	$sbit,$car0,$car0
+	add	$car0,$car1,$car1
+	add	$car2,$car1,$car1
+	st	$car1,[$tp+4]
+	srlx	$car1,32,$car2
+
+	ba	.Ltail
+	add	$tp,8,$tp
+.type	$fname,#function
+.size	$fname,(.-$fname)
+.asciz	"Montgomery Multipltication for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
+.align	32
+___
+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
+print $code;
+close STDOUT;
diff --git a/crypto/bn/asm/sparcv9a-mont.pl b/crypto/bn/asm/sparcv9a-mont.pl
new file mode 100755
index 0000000..a14205f
--- /dev/null
+++ b/crypto/bn/asm/sparcv9a-mont.pl
@@ -0,0 +1,882 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# October 2005
+#
+# "Teaser" Montgomery multiplication module for UltraSPARC. Why FPU?
+# Because unlike integer multiplier, which simply stalls whole CPU,
+# FPU is fully pipelined and can effectively emit 48 bit partial
+# product every cycle. Why not blended SPARC v9? One can argue that
+# making this module dependent on UltraSPARC VIS extension limits its
+# binary compatibility. Well yes, it does exclude SPARC64 prior-V(!)
+# implementations from compatibility matrix. But the rest, whole Sun
+# UltraSPARC family and brand new Fujitsu's SPARC64 V, all support
+# VIS extension instructions used in this module. This is considered
+# good enough to not care about HAL SPARC64 users [if any] who have
+# integer-only pure SPARCv9 module to "fall down" to.
+
+# USI&II cores currently exhibit uniform 2x improvement [over pre-
+# bn_mul_mont codebase] for all key lengths and benchmarks. On USIII
+# performance improves few percents for shorter keys and worsens few
+# percents for longer keys. This is because USIII integer multiplier
+# is >3x faster than USI&II one, which is harder to match [but see
+# TODO list below]. It should also be noted that SPARC64 V features
+# out-of-order execution, which *might* mean that integer multiplier
+# is pipelined, which in turn *might* be impossible to match... On
+# additional note, SPARC64 V implements FP Multiply-Add instruction,
+# which is perfectly usable in this context... In other words, as far
+# as Fujitsu SPARC64 V goes, talk to the author:-)
+
+# The implementation implies following "non-natural" limitations on
+# input arguments:
+# - num may not be less than 4;
+# - num has to be even;
+# Failure to meet either condition has no fatal effects, simply
+# doesn't give any performance gain.
+
+# TODO:
+# - modulo-schedule inner loop for better performance (on in-order
+#   execution core such as UltraSPARC this shall result in further
+#   noticeable(!) improvement);
+# - dedicated squaring procedure[?];
+
+######################################################################
+# November 2006
+#
+# Modulo-scheduled inner loops allow to interleave floating point and
+# integer instructions and minimize Read-After-Write penalties. This
+# results in *further* 20-50% perfromance improvement [depending on
+# key length, more for longer keys] on USI&II cores and 30-80% - on
+# USIII&IV.
+
+$fname="bn_mul_mont_fpu";
+$bits=32;
+for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
+
+if ($bits==64) {
+	$bias=2047;
+	$frame=192;
+} else {
+	$bias=0;
+	$frame=128;	# 96 rounded up to largest known cache-line
+}
+$locals=64;
+
+# In order to provide for 32-/64-bit ABI duality, I keep integers wider
+# than 32 bit in %g1-%g4 and %o0-%o5. %l0-%l7 and %i0-%i5 are used
+# exclusively for pointers, indexes and other small values...
+# int bn_mul_mont(
+$rp="%i0";	# BN_ULONG *rp,
+$ap="%i1";	# const BN_ULONG *ap,
+$bp="%i2";	# const BN_ULONG *bp,
+$np="%i3";	# const BN_ULONG *np,
+$n0="%i4";	# const BN_ULONG *n0,
+$num="%i5";	# int num);
+
+$tp="%l0";	# t[num]
+$ap_l="%l1";	# a[num],n[num] are smashed to 32-bit words and saved
+$ap_h="%l2";	# to these four vectors as double-precision FP values.
+$np_l="%l3";	# This way a bunch of fxtods are eliminated in second
+$np_h="%l4";	# loop and L1-cache aliasing is minimized...
+$i="%l5";
+$j="%l6";
+$mask="%l7";	# 16-bit mask, 0xffff
+
+$n0="%g4";	# reassigned(!) to "64-bit" register
+$carry="%i4";	# %i4 reused(!) for a carry bit
+
+# FP register naming chart
+#
+#     ..HILO
+#       dcba
+#   --------
+#        LOa
+#       LOb
+#      LOc
+#     LOd
+#      HIa
+#     HIb
+#    HIc
+#   HId
+#    ..a
+#   ..b
+$ba="%f0";    $bb="%f2";    $bc="%f4";    $bd="%f6";
+$na="%f8";    $nb="%f10";   $nc="%f12";   $nd="%f14";
+$alo="%f16";  $alo_="%f17"; $ahi="%f18";  $ahi_="%f19";
+$nlo="%f20";  $nlo_="%f21"; $nhi="%f22";  $nhi_="%f23";
+
+$dota="%f24"; $dotb="%f26";
+
+$aloa="%f32"; $alob="%f34"; $aloc="%f36"; $alod="%f38";
+$ahia="%f40"; $ahib="%f42"; $ahic="%f44"; $ahid="%f46";
+$nloa="%f48"; $nlob="%f50"; $nloc="%f52"; $nlod="%f54";
+$nhia="%f56"; $nhib="%f58"; $nhic="%f60"; $nhid="%f62";
+
+$ASI_FL16_P=0xD2;	# magic ASI value to engage 16-bit FP load
+
+$code=<<___;
+.section	".text",#alloc,#execinstr
+
+.global $fname
+.align  32
+$fname:
+	save	%sp,-$frame-$locals,%sp
+
+	cmp	$num,4
+	bl,a,pn %icc,.Lret
+	clr	%i0
+	andcc	$num,1,%g0		! $num has to be even...
+	bnz,a,pn %icc,.Lret
+	clr	%i0			! signal "unsupported input value"
+
+	srl	$num,1,$num
+	sethi	%hi(0xffff),$mask
+	ld	[%i4+0],$n0		! $n0 reassigned, remember?
+	or	$mask,%lo(0xffff),$mask
+	ld	[%i4+4],%o0
+	sllx	%o0,32,%o0
+	or	%o0,$n0,$n0		! $n0=n0[1].n0[0]
+
+	sll	$num,3,$num		! num*=8
+
+	add	%sp,$bias,%o0		! real top of stack
+	sll	$num,2,%o1
+	add	%o1,$num,%o1		! %o1=num*5
+	sub	%o0,%o1,%o0
+	and	%o0,-2048,%o0		! optimize TLB utilization
+	sub	%o0,$bias,%sp		! alloca(5*num*8)
+
+	rd	%asi,%o7		! save %asi
+	add	%sp,$bias+$frame+$locals,$tp
+	add	$tp,$num,$ap_l
+	add	$ap_l,$num,$ap_l	! [an]p_[lh] point at the vectors' ends !
+	add	$ap_l,$num,$ap_h
+	add	$ap_h,$num,$np_l
+	add	$np_l,$num,$np_h
+
+	wr	%g0,$ASI_FL16_P,%asi	! setup %asi for 16-bit FP loads
+
+	add	$rp,$num,$rp		! readjust input pointers to point
+	add	$ap,$num,$ap		! at the ends too...
+	add	$bp,$num,$bp
+	add	$np,$num,$np
+
+	stx	%o7,[%sp+$bias+$frame+48]	! save %asi
+
+	sub	%g0,$num,$i		! i=-num
+	sub	%g0,$num,$j		! j=-num
+
+	add	$ap,$j,%o3
+	add	$bp,$i,%o4
+
+	ld	[%o3+4],%g1		! bp[0]
+	ld	[%o3+0],%o0
+	ld	[%o4+4],%g5		! ap[0]
+	sllx	%g1,32,%g1
+	ld	[%o4+0],%o1
+	sllx	%g5,32,%g5
+	or	%g1,%o0,%o0
+	or	%g5,%o1,%o1
+
+	add	$np,$j,%o5
+
+	mulx	%o1,%o0,%o0		! ap[0]*bp[0]
+	mulx	$n0,%o0,%o0		! ap[0]*bp[0]*n0
+	stx	%o0,[%sp+$bias+$frame+0]
+
+	ld	[%o3+0],$alo_	! load a[j] as pair of 32-bit words
+	fzeros	$alo
+	ld	[%o3+4],$ahi_
+	fzeros	$ahi
+	ld	[%o5+0],$nlo_	! load n[j] as pair of 32-bit words
+	fzeros	$nlo
+	ld	[%o5+4],$nhi_
+	fzeros	$nhi
+
+	! transfer b[i] to FPU as 4x16-bit values
+	ldda	[%o4+2]%asi,$ba
+	fxtod	$alo,$alo
+	ldda	[%o4+0]%asi,$bb
+	fxtod	$ahi,$ahi
+	ldda	[%o4+6]%asi,$bc
+	fxtod	$nlo,$nlo
+	ldda	[%o4+4]%asi,$bd
+	fxtod	$nhi,$nhi
+
+	! transfer ap[0]*b[0]*n0 to FPU as 4x16-bit values
+	ldda	[%sp+$bias+$frame+6]%asi,$na
+	fxtod	$ba,$ba
+	ldda	[%sp+$bias+$frame+4]%asi,$nb
+	fxtod	$bb,$bb
+	ldda	[%sp+$bias+$frame+2]%asi,$nc
+	fxtod	$bc,$bc
+	ldda	[%sp+$bias+$frame+0]%asi,$nd
+	fxtod	$bd,$bd
+
+	std	$alo,[$ap_l+$j]		! save smashed ap[j] in double format
+	fxtod	$na,$na
+	std	$ahi,[$ap_h+$j]
+	fxtod	$nb,$nb
+	std	$nlo,[$np_l+$j]		! save smashed np[j] in double format
+	fxtod	$nc,$nc
+	std	$nhi,[$np_h+$j]
+	fxtod	$nd,$nd
+
+		fmuld	$alo,$ba,$aloa
+		fmuld	$nlo,$na,$nloa
+		fmuld	$alo,$bb,$alob
+		fmuld	$nlo,$nb,$nlob
+		fmuld	$alo,$bc,$aloc
+	faddd	$aloa,$nloa,$nloa
+		fmuld	$nlo,$nc,$nloc
+		fmuld	$alo,$bd,$alod
+	faddd	$alob,$nlob,$nlob
+		fmuld	$nlo,$nd,$nlod
+		fmuld	$ahi,$ba,$ahia
+	faddd	$aloc,$nloc,$nloc
+		fmuld	$nhi,$na,$nhia
+		fmuld	$ahi,$bb,$ahib
+	faddd	$alod,$nlod,$nlod
+		fmuld	$nhi,$nb,$nhib
+		fmuld	$ahi,$bc,$ahic
+	faddd	$ahia,$nhia,$nhia
+		fmuld	$nhi,$nc,$nhic
+		fmuld	$ahi,$bd,$ahid
+	faddd	$ahib,$nhib,$nhib
+		fmuld	$nhi,$nd,$nhid
+
+	faddd	$ahic,$nhic,$dota	! $nhic
+	faddd	$ahid,$nhid,$dotb	! $nhid
+
+	faddd	$nloc,$nhia,$nloc
+	faddd	$nlod,$nhib,$nlod
+
+	fdtox	$nloa,$nloa
+	fdtox	$nlob,$nlob
+	fdtox	$nloc,$nloc
+	fdtox	$nlod,$nlod
+
+	std	$nloa,[%sp+$bias+$frame+0]
+	add	$j,8,$j
+	std	$nlob,[%sp+$bias+$frame+8]
+	add	$ap,$j,%o4
+	std	$nloc,[%sp+$bias+$frame+16]
+	add	$np,$j,%o5
+	std	$nlod,[%sp+$bias+$frame+24]
+
+	ld	[%o4+0],$alo_	! load a[j] as pair of 32-bit words
+	fzeros	$alo
+	ld	[%o4+4],$ahi_
+	fzeros	$ahi
+	ld	[%o5+0],$nlo_	! load n[j] as pair of 32-bit words
+	fzeros	$nlo
+	ld	[%o5+4],$nhi_
+	fzeros	$nhi
+
+	fxtod	$alo,$alo
+	fxtod	$ahi,$ahi
+	fxtod	$nlo,$nlo
+	fxtod	$nhi,$nhi
+
+	ldx	[%sp+$bias+$frame+0],%o0
+		fmuld	$alo,$ba,$aloa
+	ldx	[%sp+$bias+$frame+8],%o1
+		fmuld	$nlo,$na,$nloa
+	ldx	[%sp+$bias+$frame+16],%o2
+		fmuld	$alo,$bb,$alob
+	ldx	[%sp+$bias+$frame+24],%o3
+		fmuld	$nlo,$nb,$nlob
+
+	srlx	%o0,16,%o7
+	std	$alo,[$ap_l+$j]		! save smashed ap[j] in double format
+		fmuld	$alo,$bc,$aloc
+	add	%o7,%o1,%o1
+	std	$ahi,[$ap_h+$j]
+		faddd	$aloa,$nloa,$nloa
+		fmuld	$nlo,$nc,$nloc
+	srlx	%o1,16,%o7
+	std	$nlo,[$np_l+$j]		! save smashed np[j] in double format
+		fmuld	$alo,$bd,$alod
+	add	%o7,%o2,%o2
+	std	$nhi,[$np_h+$j]
+		faddd	$alob,$nlob,$nlob
+		fmuld	$nlo,$nd,$nlod
+	srlx	%o2,16,%o7
+		fmuld	$ahi,$ba,$ahia
+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
+		faddd	$aloc,$nloc,$nloc
+		fmuld	$nhi,$na,$nhia
+	!and	%o0,$mask,%o0
+	!and	%o1,$mask,%o1
+	!and	%o2,$mask,%o2
+	!sllx	%o1,16,%o1
+	!sllx	%o2,32,%o2
+	!sllx	%o3,48,%o7
+	!or	%o1,%o0,%o0
+	!or	%o2,%o0,%o0
+	!or	%o7,%o0,%o0		! 64-bit result
+	srlx	%o3,16,%g1		! 34-bit carry
+		fmuld	$ahi,$bb,$ahib
+
+	faddd	$alod,$nlod,$nlod
+		fmuld	$nhi,$nb,$nhib
+		fmuld	$ahi,$bc,$ahic
+	faddd	$ahia,$nhia,$nhia
+		fmuld	$nhi,$nc,$nhic
+		fmuld	$ahi,$bd,$ahid
+	faddd	$ahib,$nhib,$nhib
+		fmuld	$nhi,$nd,$nhid
+
+	faddd	$dota,$nloa,$nloa
+	faddd	$dotb,$nlob,$nlob
+	faddd	$ahic,$nhic,$dota	! $nhic
+	faddd	$ahid,$nhid,$dotb	! $nhid
+
+	faddd	$nloc,$nhia,$nloc
+	faddd	$nlod,$nhib,$nlod
+
+	fdtox	$nloa,$nloa
+	fdtox	$nlob,$nlob
+	fdtox	$nloc,$nloc
+	fdtox	$nlod,$nlod
+
+	std	$nloa,[%sp+$bias+$frame+0]
+	std	$nlob,[%sp+$bias+$frame+8]
+	addcc	$j,8,$j
+	std	$nloc,[%sp+$bias+$frame+16]
+	bz,pn	%icc,.L1stskip
+	std	$nlod,[%sp+$bias+$frame+24]
+
+.align	32			! incidentally already aligned !
+.L1st:
+	add	$ap,$j,%o4
+	add	$np,$j,%o5
+	ld	[%o4+0],$alo_	! load a[j] as pair of 32-bit words
+	fzeros	$alo
+	ld	[%o4+4],$ahi_
+	fzeros	$ahi
+	ld	[%o5+0],$nlo_	! load n[j] as pair of 32-bit words
+	fzeros	$nlo
+	ld	[%o5+4],$nhi_
+	fzeros	$nhi
+
+	fxtod	$alo,$alo
+	fxtod	$ahi,$ahi
+	fxtod	$nlo,$nlo
+	fxtod	$nhi,$nhi
+
+	ldx	[%sp+$bias+$frame+0],%o0
+		fmuld	$alo,$ba,$aloa
+	ldx	[%sp+$bias+$frame+8],%o1
+		fmuld	$nlo,$na,$nloa
+	ldx	[%sp+$bias+$frame+16],%o2
+		fmuld	$alo,$bb,$alob
+	ldx	[%sp+$bias+$frame+24],%o3
+		fmuld	$nlo,$nb,$nlob
+
+	srlx	%o0,16,%o7
+	std	$alo,[$ap_l+$j]		! save smashed ap[j] in double format
+		fmuld	$alo,$bc,$aloc
+	add	%o7,%o1,%o1
+	std	$ahi,[$ap_h+$j]
+		faddd	$aloa,$nloa,$nloa
+		fmuld	$nlo,$nc,$nloc
+	srlx	%o1,16,%o7
+	std	$nlo,[$np_l+$j]		! save smashed np[j] in double format
+		fmuld	$alo,$bd,$alod
+	add	%o7,%o2,%o2
+	std	$nhi,[$np_h+$j]
+		faddd	$alob,$nlob,$nlob
+		fmuld	$nlo,$nd,$nlod
+	srlx	%o2,16,%o7
+		fmuld	$ahi,$ba,$ahia
+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
+	and	%o0,$mask,%o0
+		faddd	$aloc,$nloc,$nloc
+		fmuld	$nhi,$na,$nhia
+	and	%o1,$mask,%o1
+	and	%o2,$mask,%o2
+		fmuld	$ahi,$bb,$ahib
+	sllx	%o1,16,%o1
+		faddd	$alod,$nlod,$nlod
+		fmuld	$nhi,$nb,$nhib
+	sllx	%o2,32,%o2
+		fmuld	$ahi,$bc,$ahic
+	sllx	%o3,48,%o7
+	or	%o1,%o0,%o0
+		faddd	$ahia,$nhia,$nhia
+		fmuld	$nhi,$nc,$nhic
+	or	%o2,%o0,%o0
+		fmuld	$ahi,$bd,$ahid
+	or	%o7,%o0,%o0		! 64-bit result
+		faddd	$ahib,$nhib,$nhib
+		fmuld	$nhi,$nd,$nhid
+	addcc	%g1,%o0,%o0
+		faddd	$dota,$nloa,$nloa
+	srlx	%o3,16,%g1		! 34-bit carry
+		faddd	$dotb,$nlob,$nlob
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	stx	%o0,[$tp]		! tp[j-1]=
+
+	faddd	$ahic,$nhic,$dota	! $nhic
+	faddd	$ahid,$nhid,$dotb	! $nhid
+
+	faddd	$nloc,$nhia,$nloc
+	faddd	$nlod,$nhib,$nlod
+
+	fdtox	$nloa,$nloa
+	fdtox	$nlob,$nlob
+	fdtox	$nloc,$nloc
+	fdtox	$nlod,$nlod
+
+	std	$nloa,[%sp+$bias+$frame+0]
+	std	$nlob,[%sp+$bias+$frame+8]
+	std	$nloc,[%sp+$bias+$frame+16]
+	std	$nlod,[%sp+$bias+$frame+24]
+
+	addcc	$j,8,$j
+	bnz,pt	%icc,.L1st
+	add	$tp,8,$tp
+
+.L1stskip:
+	fdtox	$dota,$dota
+	fdtox	$dotb,$dotb
+
+	ldx	[%sp+$bias+$frame+0],%o0
+	ldx	[%sp+$bias+$frame+8],%o1
+	ldx	[%sp+$bias+$frame+16],%o2
+	ldx	[%sp+$bias+$frame+24],%o3
+
+	srlx	%o0,16,%o7
+	std	$dota,[%sp+$bias+$frame+32]
+	add	%o7,%o1,%o1
+	std	$dotb,[%sp+$bias+$frame+40]
+	srlx	%o1,16,%o7
+	add	%o7,%o2,%o2
+	srlx	%o2,16,%o7
+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
+	and	%o0,$mask,%o0
+	and	%o1,$mask,%o1
+	and	%o2,$mask,%o2
+	sllx	%o1,16,%o1
+	sllx	%o2,32,%o2
+	sllx	%o3,48,%o7
+	or	%o1,%o0,%o0
+	or	%o2,%o0,%o0
+	or	%o7,%o0,%o0		! 64-bit result
+	ldx	[%sp+$bias+$frame+32],%o4
+	addcc	%g1,%o0,%o0
+	ldx	[%sp+$bias+$frame+40],%o5
+	srlx	%o3,16,%g1		! 34-bit carry
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	stx	%o0,[$tp]		! tp[j-1]=
+	add	$tp,8,$tp
+
+	srlx	%o4,16,%o7
+	add	%o7,%o5,%o5
+	and	%o4,$mask,%o4
+	sllx	%o5,16,%o7
+	or	%o7,%o4,%o4
+	addcc	%g1,%o4,%o4
+	srlx	%o5,48,%g1
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	mov	%g1,$carry
+	stx	%o4,[$tp]		! tp[num-1]=
+
+	ba	.Louter
+	add	$i,8,$i
+.align	32
+.Louter:
+	sub	%g0,$num,$j		! j=-num
+	add	%sp,$bias+$frame+$locals,$tp
+
+	add	$ap,$j,%o3
+	add	$bp,$i,%o4
+
+	ld	[%o3+4],%g1		! bp[i]
+	ld	[%o3+0],%o0
+	ld	[%o4+4],%g5		! ap[0]
+	sllx	%g1,32,%g1
+	ld	[%o4+0],%o1
+	sllx	%g5,32,%g5
+	or	%g1,%o0,%o0
+	or	%g5,%o1,%o1
+
+	ldx	[$tp],%o2		! tp[0]
+	mulx	%o1,%o0,%o0
+	addcc	%o2,%o0,%o0
+	mulx	$n0,%o0,%o0		! (ap[0]*bp[i]+t[0])*n0
+	stx	%o0,[%sp+$bias+$frame+0]
+
+	! transfer b[i] to FPU as 4x16-bit values
+	ldda	[%o4+2]%asi,$ba
+	ldda	[%o4+0]%asi,$bb
+	ldda	[%o4+6]%asi,$bc
+	ldda	[%o4+4]%asi,$bd
+
+	! transfer (ap[0]*b[i]+t[0])*n0 to FPU as 4x16-bit values
+	ldda	[%sp+$bias+$frame+6]%asi,$na
+	fxtod	$ba,$ba
+	ldda	[%sp+$bias+$frame+4]%asi,$nb
+	fxtod	$bb,$bb
+	ldda	[%sp+$bias+$frame+2]%asi,$nc
+	fxtod	$bc,$bc
+	ldda	[%sp+$bias+$frame+0]%asi,$nd
+	fxtod	$bd,$bd
+	ldd	[$ap_l+$j],$alo		! load a[j] in double format
+	fxtod	$na,$na
+	ldd	[$ap_h+$j],$ahi
+	fxtod	$nb,$nb
+	ldd	[$np_l+$j],$nlo		! load n[j] in double format
+	fxtod	$nc,$nc
+	ldd	[$np_h+$j],$nhi
+	fxtod	$nd,$nd
+
+		fmuld	$alo,$ba,$aloa
+		fmuld	$nlo,$na,$nloa
+		fmuld	$alo,$bb,$alob
+		fmuld	$nlo,$nb,$nlob
+		fmuld	$alo,$bc,$aloc
+	faddd	$aloa,$nloa,$nloa
+		fmuld	$nlo,$nc,$nloc
+		fmuld	$alo,$bd,$alod
+	faddd	$alob,$nlob,$nlob
+		fmuld	$nlo,$nd,$nlod
+		fmuld	$ahi,$ba,$ahia
+	faddd	$aloc,$nloc,$nloc
+		fmuld	$nhi,$na,$nhia
+		fmuld	$ahi,$bb,$ahib
+	faddd	$alod,$nlod,$nlod
+		fmuld	$nhi,$nb,$nhib
+		fmuld	$ahi,$bc,$ahic
+	faddd	$ahia,$nhia,$nhia
+		fmuld	$nhi,$nc,$nhic
+		fmuld	$ahi,$bd,$ahid
+	faddd	$ahib,$nhib,$nhib
+		fmuld	$nhi,$nd,$nhid
+
+	faddd	$ahic,$nhic,$dota	! $nhic
+	faddd	$ahid,$nhid,$dotb	! $nhid
+
+	faddd	$nloc,$nhia,$nloc
+	faddd	$nlod,$nhib,$nlod
+
+	fdtox	$nloa,$nloa
+	fdtox	$nlob,$nlob
+	fdtox	$nloc,$nloc
+	fdtox	$nlod,$nlod
+
+	std	$nloa,[%sp+$bias+$frame+0]
+	std	$nlob,[%sp+$bias+$frame+8]
+	std	$nloc,[%sp+$bias+$frame+16]
+	add	$j,8,$j
+	std	$nlod,[%sp+$bias+$frame+24]
+
+	ldd	[$ap_l+$j],$alo		! load a[j] in double format
+	ldd	[$ap_h+$j],$ahi
+	ldd	[$np_l+$j],$nlo		! load n[j] in double format
+	ldd	[$np_h+$j],$nhi
+
+		fmuld	$alo,$ba,$aloa
+		fmuld	$nlo,$na,$nloa
+		fmuld	$alo,$bb,$alob
+		fmuld	$nlo,$nb,$nlob
+		fmuld	$alo,$bc,$aloc
+	ldx	[%sp+$bias+$frame+0],%o0
+		faddd	$aloa,$nloa,$nloa
+		fmuld	$nlo,$nc,$nloc
+	ldx	[%sp+$bias+$frame+8],%o1
+		fmuld	$alo,$bd,$alod
+	ldx	[%sp+$bias+$frame+16],%o2
+		faddd	$alob,$nlob,$nlob
+		fmuld	$nlo,$nd,$nlod
+	ldx	[%sp+$bias+$frame+24],%o3
+		fmuld	$ahi,$ba,$ahia
+
+	srlx	%o0,16,%o7
+		faddd	$aloc,$nloc,$nloc
+		fmuld	$nhi,$na,$nhia
+	add	%o7,%o1,%o1
+		fmuld	$ahi,$bb,$ahib
+	srlx	%o1,16,%o7
+		faddd	$alod,$nlod,$nlod
+		fmuld	$nhi,$nb,$nhib
+	add	%o7,%o2,%o2
+		fmuld	$ahi,$bc,$ahic
+	srlx	%o2,16,%o7
+		faddd	$ahia,$nhia,$nhia
+		fmuld	$nhi,$nc,$nhic
+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
+	! why?
+	and	%o0,$mask,%o0
+		fmuld	$ahi,$bd,$ahid
+	and	%o1,$mask,%o1
+	and	%o2,$mask,%o2
+		faddd	$ahib,$nhib,$nhib
+		fmuld	$nhi,$nd,$nhid
+	sllx	%o1,16,%o1
+		faddd	$dota,$nloa,$nloa
+	sllx	%o2,32,%o2
+		faddd	$dotb,$nlob,$nlob
+	sllx	%o3,48,%o7
+	or	%o1,%o0,%o0
+		faddd	$ahic,$nhic,$dota	! $nhic
+	or	%o2,%o0,%o0
+		faddd	$ahid,$nhid,$dotb	! $nhid
+	or	%o7,%o0,%o0		! 64-bit result
+	ldx	[$tp],%o7
+		faddd	$nloc,$nhia,$nloc
+	addcc	%o7,%o0,%o0
+	! end-of-why?
+		faddd	$nlod,$nhib,$nlod
+	srlx	%o3,16,%g1		! 34-bit carry
+		fdtox	$nloa,$nloa
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	fdtox	$nlob,$nlob
+	fdtox	$nloc,$nloc
+	fdtox	$nlod,$nlod
+
+	std	$nloa,[%sp+$bias+$frame+0]
+	std	$nlob,[%sp+$bias+$frame+8]
+	addcc	$j,8,$j
+	std	$nloc,[%sp+$bias+$frame+16]
+	bz,pn	%icc,.Linnerskip
+	std	$nlod,[%sp+$bias+$frame+24]
+
+	ba	.Linner
+	nop
+.align	32
+.Linner:
+	ldd	[$ap_l+$j],$alo		! load a[j] in double format
+	ldd	[$ap_h+$j],$ahi
+	ldd	[$np_l+$j],$nlo		! load n[j] in double format
+	ldd	[$np_h+$j],$nhi
+
+		fmuld	$alo,$ba,$aloa
+		fmuld	$nlo,$na,$nloa
+		fmuld	$alo,$bb,$alob
+		fmuld	$nlo,$nb,$nlob
+		fmuld	$alo,$bc,$aloc
+	ldx	[%sp+$bias+$frame+0],%o0
+		faddd	$aloa,$nloa,$nloa
+		fmuld	$nlo,$nc,$nloc
+	ldx	[%sp+$bias+$frame+8],%o1
+		fmuld	$alo,$bd,$alod
+	ldx	[%sp+$bias+$frame+16],%o2
+		faddd	$alob,$nlob,$nlob
+		fmuld	$nlo,$nd,$nlod
+	ldx	[%sp+$bias+$frame+24],%o3
+		fmuld	$ahi,$ba,$ahia
+
+	srlx	%o0,16,%o7
+		faddd	$aloc,$nloc,$nloc
+		fmuld	$nhi,$na,$nhia
+	add	%o7,%o1,%o1
+		fmuld	$ahi,$bb,$ahib
+	srlx	%o1,16,%o7
+		faddd	$alod,$nlod,$nlod
+		fmuld	$nhi,$nb,$nhib
+	add	%o7,%o2,%o2
+		fmuld	$ahi,$bc,$ahic
+	srlx	%o2,16,%o7
+		faddd	$ahia,$nhia,$nhia
+		fmuld	$nhi,$nc,$nhic
+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
+	and	%o0,$mask,%o0
+		fmuld	$ahi,$bd,$ahid
+	and	%o1,$mask,%o1
+	and	%o2,$mask,%o2
+		faddd	$ahib,$nhib,$nhib
+		fmuld	$nhi,$nd,$nhid
+	sllx	%o1,16,%o1
+		faddd	$dota,$nloa,$nloa
+	sllx	%o2,32,%o2
+		faddd	$dotb,$nlob,$nlob
+	sllx	%o3,48,%o7
+	or	%o1,%o0,%o0
+		faddd	$ahic,$nhic,$dota	! $nhic
+	or	%o2,%o0,%o0
+		faddd	$ahid,$nhid,$dotb	! $nhid
+	or	%o7,%o0,%o0		! 64-bit result
+		faddd	$nloc,$nhia,$nloc
+	addcc	%g1,%o0,%o0
+	ldx	[$tp+8],%o7		! tp[j]
+		faddd	$nlod,$nhib,$nlod
+	srlx	%o3,16,%g1		! 34-bit carry
+		fdtox	$nloa,$nloa
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+		fdtox	$nlob,$nlob
+	addcc	%o7,%o0,%o0
+		fdtox	$nloc,$nloc
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	stx	%o0,[$tp]		! tp[j-1]
+		fdtox	$nlod,$nlod
+
+	std	$nloa,[%sp+$bias+$frame+0]
+	std	$nlob,[%sp+$bias+$frame+8]
+	std	$nloc,[%sp+$bias+$frame+16]
+	addcc	$j,8,$j
+	std	$nlod,[%sp+$bias+$frame+24]
+	bnz,pt	%icc,.Linner
+	add	$tp,8,$tp
+
+.Linnerskip:
+	fdtox	$dota,$dota
+	fdtox	$dotb,$dotb
+
+	ldx	[%sp+$bias+$frame+0],%o0
+	ldx	[%sp+$bias+$frame+8],%o1
+	ldx	[%sp+$bias+$frame+16],%o2
+	ldx	[%sp+$bias+$frame+24],%o3
+
+	srlx	%o0,16,%o7
+	std	$dota,[%sp+$bias+$frame+32]
+	add	%o7,%o1,%o1
+	std	$dotb,[%sp+$bias+$frame+40]
+	srlx	%o1,16,%o7
+	add	%o7,%o2,%o2
+	srlx	%o2,16,%o7
+	add	%o7,%o3,%o3		! %o3.%o2[0..15].%o1[0..15].%o0[0..15]
+	and	%o0,$mask,%o0
+	and	%o1,$mask,%o1
+	and	%o2,$mask,%o2
+	sllx	%o1,16,%o1
+	sllx	%o2,32,%o2
+	sllx	%o3,48,%o7
+	or	%o1,%o0,%o0
+	or	%o2,%o0,%o0
+	ldx	[%sp+$bias+$frame+32],%o4
+	or	%o7,%o0,%o0		! 64-bit result
+	ldx	[%sp+$bias+$frame+40],%o5
+	addcc	%g1,%o0,%o0
+	ldx	[$tp+8],%o7		! tp[j]
+	srlx	%o3,16,%g1		! 34-bit carry
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	addcc	%o7,%o0,%o0
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	stx	%o0,[$tp]		! tp[j-1]
+	add	$tp,8,$tp
+
+	srlx	%o4,16,%o7
+	add	%o7,%o5,%o5
+	and	%o4,$mask,%o4
+	sllx	%o5,16,%o7
+	or	%o7,%o4,%o4
+	addcc	%g1,%o4,%o4
+	srlx	%o5,48,%g1
+	bcs,a	%xcc,.+8
+	add	%g1,1,%g1
+
+	addcc	$carry,%o4,%o4
+	stx	%o4,[$tp]		! tp[num-1]
+	mov	%g1,$carry
+	bcs,a	%xcc,.+8
+	add	$carry,1,$carry
+
+	addcc	$i,8,$i
+	bnz	%icc,.Louter
+	nop
+
+	add	$tp,8,$tp		! adjust tp to point at the end
+	orn	%g0,%g0,%g4
+	sub	%g0,$num,%o7		! n=-num
+	ba	.Lsub
+	subcc	%g0,%g0,%g0		! clear %icc.c
+
+.align	32
+.Lsub:
+	ldx	[$tp+%o7],%o0
+	add	$np,%o7,%g1
+	ld	[%g1+0],%o2
+	ld	[%g1+4],%o3
+	srlx	%o0,32,%o1
+	subccc	%o0,%o2,%o2
+	add	$rp,%o7,%g1
+	subccc	%o1,%o3,%o3
+	st	%o2,[%g1+0]
+	add	%o7,8,%o7
+	brnz,pt	%o7,.Lsub
+	st	%o3,[%g1+4]
+	subc	$carry,0,%g4
+	sub	%g0,$num,%o7		! n=-num
+	ba	.Lcopy
+	nop
+
+.align	32
+.Lcopy:
+	ldx	[$tp+%o7],%o0
+	add	$rp,%o7,%g1
+	ld	[%g1+0],%o2
+	ld	[%g1+4],%o3
+	stx	%g0,[$tp+%o7]
+	and	%o0,%g4,%o0
+	srlx	%o0,32,%o1
+	andn	%o2,%g4,%o2
+	andn	%o3,%g4,%o3
+	or	%o2,%o0,%o0
+	or	%o3,%o1,%o1
+	st	%o0,[%g1+0]
+	add	%o7,8,%o7
+	brnz,pt	%o7,.Lcopy
+	st	%o1,[%g1+4]
+	sub	%g0,$num,%o7		! n=-num
+
+.Lzap:
+	stx	%g0,[$ap_l+%o7]
+	stx	%g0,[$ap_h+%o7]
+	stx	%g0,[$np_l+%o7]
+	stx	%g0,[$np_h+%o7]
+	add	%o7,8,%o7
+	brnz,pt	%o7,.Lzap
+	nop
+
+	ldx	[%sp+$bias+$frame+48],%o7
+	wr	%g0,%o7,%asi		! restore %asi
+
+	mov	1,%i0
+.Lret:
+	ret
+	restore
+.type   $fname,#function
+.size	$fname,(.-$fname)
+.asciz	"Montgomery Multipltication for UltraSPARC, CRYPTOGAMS by <appro\@openssl.org>"
+.align	32
+___
+
+$code =~ s/\`([^\`]*)\`/eval($1)/gem;
+
+# Below substitution makes it possible to compile without demanding
+# VIS extentions on command line, e.g. -xarch=v9 vs. -xarch=v9a. I
+# dare to do this, because VIS capability is detected at run-time now
+# and this routine is not called on CPU not capable to execute it. Do
+# note that fzeros is not the only VIS dependency! Another dependency
+# is implicit and is just _a_ numerical value loaded to %asi register,
+# which assembler can't recognize as VIS specific...
+$code =~ s/fzeros\s+%f([0-9]+)/
+	   sprintf(".word\t0x%x\t! fzeros %%f%d",0x81b00c20|($1<<25),$1)
+	  /gem;
+
+print $code;
+# flush
+close STDOUT;
diff --git a/crypto/bn/asm/via-mont.pl b/crypto/bn/asm/via-mont.pl
new file mode 100644
index 0000000..c046a51
--- /dev/null
+++ b/crypto/bn/asm/via-mont.pl
@@ -0,0 +1,242 @@
+#!/usr/bin/env perl
+#
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+#
+# Wrapper around 'rep montmul', VIA-specific instruction accessing
+# PadLock Montgomery Multiplier. The wrapper is designed as drop-in
+# replacement for OpenSSL bn_mul_mont [first implemented in 0.9.9].
+#
+# Below are interleaved outputs from 'openssl speed rsa dsa' for 4
+# different software configurations on 1.5GHz VIA Esther processor.
+# Lines marked with "software integer" denote performance of hand-
+# coded integer-only assembler found in OpenSSL 0.9.7. "Software SSE2"
+# refers to hand-coded SSE2 Montgomery multiplication procedure found
+# OpenSSL 0.9.9. "Hardware VIA SDK" refers to padlock_pmm routine from
+# Padlock SDK 2.0.1 available for download from VIA, which naturally
+# utilizes the magic 'repz montmul' instruction. And finally "hardware
+# this" refers to *this* implementation which also uses 'repz montmul'
+#
+#                   sign    verify    sign/s verify/s
+# rsa  512 bits 0.001720s 0.000140s    581.4   7149.7	software integer
+# rsa  512 bits 0.000690s 0.000086s   1450.3  11606.0	software SSE2
+# rsa  512 bits 0.006136s 0.000201s    163.0   4974.5	hardware VIA SDK
+# rsa  512 bits 0.000712s 0.000050s   1404.9  19858.5	hardware this
+#
+# rsa 1024 bits 0.008518s 0.000413s    117.4   2420.8	software integer
+# rsa 1024 bits 0.004275s 0.000277s    233.9   3609.7	software SSE2
+# rsa 1024 bits 0.012136s 0.000260s     82.4   3844.5	hardware VIA SDK
+# rsa 1024 bits 0.002522s 0.000116s    396.5   8650.9	hardware this
+#
+# rsa 2048 bits 0.050101s 0.001371s     20.0    729.6	software integer
+# rsa 2048 bits 0.030273s 0.001008s     33.0    991.9	software SSE2
+# rsa 2048 bits 0.030833s 0.000976s     32.4   1025.1	hardware VIA SDK
+# rsa 2048 bits 0.011879s 0.000342s     84.2   2921.7	hardware this
+#
+# rsa 4096 bits 0.327097s 0.004859s      3.1    205.8	software integer
+# rsa 4096 bits 0.229318s 0.003859s      4.4    259.2	software SSE2
+# rsa 4096 bits 0.233953s 0.003274s      4.3    305.4	hardware VIA SDK
+# rsa 4096 bits 0.070493s 0.001166s     14.2    857.6	hardware this
+#
+# dsa  512 bits 0.001342s 0.001651s    745.2    605.7	software integer
+# dsa  512 bits 0.000844s 0.000987s   1185.3   1013.1	software SSE2
+# dsa  512 bits 0.001902s 0.002247s    525.6    444.9	hardware VIA SDK
+# dsa  512 bits 0.000458s 0.000524s   2182.2   1909.1	hardware this
+#
+# dsa 1024 bits 0.003964s 0.004926s    252.3    203.0	software integer
+# dsa 1024 bits 0.002686s 0.003166s    372.3    315.8	software SSE2
+# dsa 1024 bits 0.002397s 0.002823s    417.1    354.3	hardware VIA SDK
+# dsa 1024 bits 0.000978s 0.001170s   1022.2    855.0	hardware this
+#
+# dsa 2048 bits 0.013280s 0.016518s     75.3     60.5	software integer
+# dsa 2048 bits 0.009911s 0.011522s    100.9     86.8	software SSE2
+# dsa 2048 bits 0.009542s 0.011763s    104.8     85.0	hardware VIA SDK
+# dsa 2048 bits 0.002884s 0.003352s    346.8    298.3	hardware this
+#
+# To give you some other reference point here is output for 2.4GHz P4
+# running hand-coded SSE2 bn_mul_mont found in 0.9.9, i.e. "software
+# SSE2" in above terms.
+#
+# rsa  512 bits 0.000407s 0.000047s   2454.2  21137.0
+# rsa 1024 bits 0.002426s 0.000141s    412.1   7100.0
+# rsa 2048 bits 0.015046s 0.000491s     66.5   2034.9
+# rsa 4096 bits 0.109770s 0.002379s      9.1    420.3
+# dsa  512 bits 0.000438s 0.000525s   2281.1   1904.1
+# dsa 1024 bits 0.001346s 0.001595s    742.7    627.0
+# dsa 2048 bits 0.004745s 0.005582s    210.7    179.1
+#
+# Conclusions: 
+# - VIA SDK leaves a *lot* of room for improvement (which this
+#   implementation successfully fills:-);
+# - 'rep montmul' gives up to >3x performance improvement depending on
+#   key length;
+# - in terms of absolute performance it delivers approximately as much
+#   as modern out-of-order 32-bit cores [again, for longer keys].
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"via-mont.pl");
+
+# int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
+$func="bn_mul_mont_padlock";
+
+$pad=16*1;	# amount of reserved bytes on top of every vector
+
+# stack layout
+$mZeroPrime=&DWP(0,"esp");		# these are specified by VIA
+$A=&DWP(4,"esp");
+$B=&DWP(8,"esp");
+$T=&DWP(12,"esp");
+$M=&DWP(16,"esp");
+$scratch=&DWP(20,"esp");
+$rp=&DWP(24,"esp");			# these are mine
+$sp=&DWP(28,"esp");
+# &DWP(32,"esp")			# 32 byte scratch area
+# &DWP(64+(4*$num+$pad)*0,"esp")	# padded tp[num]
+# &DWP(64+(4*$num+$pad)*1,"esp")	# padded copy of ap[num]
+# &DWP(64+(4*$num+$pad)*2,"esp")	# padded copy of bp[num]
+# &DWP(64+(4*$num+$pad)*3,"esp")	# padded copy of np[num]
+# Note that SDK suggests to unconditionally allocate 2K per vector. This
+# has quite an impact on performance. It naturally depends on key length,
+# but to give an example 1024 bit private RSA key operations suffer >30%
+# penalty. I allocate only as much as actually required...
+
+&function_begin($func);
+	&xor	("eax","eax");
+	&mov	("ecx",&wparam(5));	# num
+	# meet VIA's limitations for num [note that the specification
+	# expresses them in bits, while we work with amount of 32-bit words]
+	&test	("ecx",3);
+	&jnz	(&label("leave"));	# num % 4 != 0
+	&cmp	("ecx",8);
+	&jb	(&label("leave"));	# num < 8
+	&cmp	("ecx",1024);
+	&ja	(&label("leave"));	# num > 1024
+
+	&pushf	();
+	&cld	();
+
+	&mov	("edi",&wparam(0));	# rp
+	&mov	("eax",&wparam(1));	# ap
+	&mov	("ebx",&wparam(2));	# bp
+	&mov	("edx",&wparam(3));	# np
+	&mov	("esi",&wparam(4));	# n0
+	&mov	("esi",&DWP(0,"esi"));	# *n0
+
+	&lea	("ecx",&DWP($pad,"","ecx",4));	# ecx becomes vector size in bytes
+	&lea	("ebp",&DWP(64,"","ecx",4));	# allocate 4 vectors + 64 bytes
+	&neg	("ebp");
+	&add	("ebp","esp");
+	&and	("ebp",-64);		# align to cache-line
+	&xchg	("ebp","esp");		# alloca
+
+	&mov	($rp,"edi");		# save rp
+	&mov	($sp,"ebp");		# save esp
+
+	&mov	($mZeroPrime,"esi");
+	&lea	("esi",&DWP(64,"esp"));	# tp
+	&mov	($T,"esi");
+	&lea	("edi",&DWP(32,"esp"));	# scratch area
+	&mov	($scratch,"edi");
+	&mov	("esi","eax");
+
+	&lea	("ebp",&DWP(-$pad,"ecx"));
+	&shr	("ebp",2);		# restore original num value in ebp
+
+	&xor	("eax","eax");
+
+	&mov	("ecx","ebp");
+	&lea	("ecx",&DWP((32+$pad)/4,"ecx"));# padded tp + scratch
+	&data_byte(0xf3,0xab);		# rep stosl, bzero
+
+	&mov	("ecx","ebp");
+	&lea	("edi",&DWP(64+$pad,"esp","ecx",4));# pointer to ap copy
+	&mov	($A,"edi");
+	&data_byte(0xf3,0xa5);		# rep movsl, memcpy
+	&mov	("ecx",$pad/4);
+	&data_byte(0xf3,0xab);		# rep stosl, bzero pad
+	# edi points at the end of padded ap copy...
+
+	&mov	("ecx","ebp");
+	&mov	("esi","ebx");
+	&mov	($B,"edi");
+	&data_byte(0xf3,0xa5);		# rep movsl, memcpy
+	&mov	("ecx",$pad/4);
+	&data_byte(0xf3,0xab);		# rep stosl, bzero pad
+	# edi points at the end of padded bp copy...
+
+	&mov	("ecx","ebp");
+	&mov	("esi","edx");
+	&mov	($M,"edi");
+	&data_byte(0xf3,0xa5);		# rep movsl, memcpy
+	&mov	("ecx",$pad/4);
+	&data_byte(0xf3,0xab);		# rep stosl, bzero pad
+	# edi points at the end of padded np copy...
+
+	# let magic happen...
+	&mov	("ecx","ebp");
+	&mov	("esi","esp");
+	&shl	("ecx",5);		# convert word counter to bit counter
+	&align	(4);
+	&data_byte(0xf3,0x0f,0xa6,0xc0);# rep montmul
+
+	&mov	("ecx","ebp");
+	&lea	("esi",&DWP(64,"esp"));		# tp
+	# edi still points at the end of padded np copy...
+	&neg	("ebp");
+	&lea	("ebp",&DWP(-$pad,"edi","ebp",4));	# so just "rewind"
+	&mov	("edi",$rp);			# restore rp
+	&xor	("edx","edx");			# i=0 and clear CF
+
+&set_label("sub",8);
+	&mov	("eax",&DWP(0,"esi","edx",4));
+	&sbb	("eax",&DWP(0,"ebp","edx",4));
+	&mov	(&DWP(0,"edi","edx",4),"eax");	# rp[i]=tp[i]-np[i]
+	&lea	("edx",&DWP(1,"edx"));		# i++
+	&loop	(&label("sub"));		# doesn't affect CF!
+
+	&mov	("eax",&DWP(0,"esi","edx",4));	# upmost overflow bit
+	&sbb	("eax",0);
+	&and	("esi","eax");
+	&not	("eax");
+	&mov	("ebp","edi");
+	&and	("ebp","eax");
+	&or	("esi","ebp");			# tp=carry?tp:rp
+
+	&mov	("ecx","edx");			# num
+	&xor	("edx","edx");			# i=0
+
+&set_label("copy",8);
+	&mov	("eax",&DWP(0,"esi","edx",4));
+	&mov	(&DWP(64,"esp","edx",4),"ecx");	# zap tp
+	&mov	(&DWP(0,"edi","edx",4),"eax");
+	&lea	("edx",&DWP(1,"edx"));		# i++
+	&loop	(&label("copy"));
+
+	&mov	("ebp",$sp);
+	&xor	("eax","eax");
+
+	&mov	("ecx",64/4);
+	&mov	("edi","esp");		# zap frame including scratch area
+	&data_byte(0xf3,0xab);		# rep stosl, bzero
+
+	# zap copies of ap, bp and np
+	&lea	("edi",&DWP(64+$pad,"esp","edx",4));# pointer to ap
+	&lea	("ecx",&DWP(3*$pad/4,"edx","edx",2));
+	&data_byte(0xf3,0xab);		# rep stosl, bzero
+
+	&mov	("esp","ebp");
+	&inc	("eax");		# signal "done"
+	&popf	();
+&set_label("leave");
+&function_end($func);
+
+&asciz("Padlock Montgomery Multiplication, CRYPTOGAMS by <appro\@openssl.org>");
+
+&asm_finish();
diff --git a/crypto/bn/asm/x86-mont.pl b/crypto/bn/asm/x86-mont.pl
new file mode 100755
index 0000000..5cd3cd2
--- /dev/null
+++ b/crypto/bn/asm/x86-mont.pl
@@ -0,0 +1,591 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# project. The module is, however, dual licensed under OpenSSL and
+# CRYPTOGAMS licenses depending on where you obtain it. For further
+# details see http://www.openssl.org/~appro/cryptogams/.
+# ====================================================================
+
+# October 2005
+#
+# This is a "teaser" code, as it can be improved in several ways...
+# First of all non-SSE2 path should be implemented (yes, for now it
+# performs Montgomery multiplication/convolution only on SSE2-capable
+# CPUs such as P4, others fall down to original code). Then inner loop
+# can be unrolled and modulo-scheduled to improve ILP and possibly
+# moved to 128-bit XMM register bank (though it would require input
+# rearrangement and/or increase bus bandwidth utilization). Dedicated
+# squaring procedure should give further performance improvement...
+# Yet, for being draft, the code improves rsa512 *sign* benchmark by
+# 110%(!), rsa1024 one - by 70% and rsa4096 - by 20%:-)
+
+# December 2006
+#
+# Modulo-scheduling SSE2 loops results in further 15-20% improvement.
+# Integer-only code [being equipped with dedicated squaring procedure]
+# gives ~40% on rsa512 sign benchmark...
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],$0);
+
+$sse2=0;
+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
+
+&external_label("OPENSSL_ia32cap_P") if ($sse2);
+
+&function_begin("bn_mul_mont");
+
+$i="edx";
+$j="ecx";
+$ap="esi";	$tp="esi";		# overlapping variables!!!
+$rp="edi";	$bp="edi";		# overlapping variables!!!
+$np="ebp";
+$num="ebx";
+
+$_num=&DWP(4*0,"esp");			# stack top layout
+$_rp=&DWP(4*1,"esp");
+$_ap=&DWP(4*2,"esp");
+$_bp=&DWP(4*3,"esp");
+$_np=&DWP(4*4,"esp");
+$_n0=&DWP(4*5,"esp");	$_n0q=&QWP(4*5,"esp");
+$_sp=&DWP(4*6,"esp");
+$_bpend=&DWP(4*7,"esp");
+$frame=32;				# size of above frame rounded up to 16n
+
+	&xor	("eax","eax");
+	&mov	("edi",&wparam(5));	# int num
+	&cmp	("edi",4);
+	&jl	(&label("just_leave"));
+
+	&lea	("esi",&wparam(0));	# put aside pointer to argument block
+	&lea	("edx",&wparam(1));	# load ap
+	&mov	("ebp","esp");		# saved stack pointer!
+	&add	("edi",2);		# extra two words on top of tp
+	&neg	("edi");
+	&lea	("esp",&DWP(-$frame,"esp","edi",4));	# alloca($frame+4*(num+2))
+	&neg	("edi");
+
+	# minimize cache contention by arraning 2K window between stack
+	# pointer and ap argument [np is also position sensitive vector,
+	# but it's assumed to be near ap, as it's allocated at ~same
+	# time].
+	&mov	("eax","esp");
+	&sub	("eax","edx");
+	&and	("eax",2047);
+	&sub	("esp","eax");		# this aligns sp and ap modulo 2048
+
+	&xor	("edx","esp");
+	&and	("edx",2048);
+	&xor	("edx",2048);
+	&sub	("esp","edx");		# this splits them apart modulo 4096
+
+	&and	("esp",-64);		# align to cache line
+
+	################################# load argument block...
+	&mov	("eax",&DWP(0*4,"esi"));# BN_ULONG *rp
+	&mov	("ebx",&DWP(1*4,"esi"));# const BN_ULONG *ap
+	&mov	("ecx",&DWP(2*4,"esi"));# const BN_ULONG *bp
+	&mov	("edx",&DWP(3*4,"esi"));# const BN_ULONG *np
+	&mov	("esi",&DWP(4*4,"esi"));# const BN_ULONG *n0
+	#&mov	("edi",&DWP(5*4,"esi"));# int num
+
+	&mov	("esi",&DWP(0,"esi"));	# pull n0[0]
+	&mov	($_rp,"eax");		# ... save a copy of argument block
+	&mov	($_ap,"ebx");
+	&mov	($_bp,"ecx");
+	&mov	($_np,"edx");
+	&mov	($_n0,"esi");
+	&lea	($num,&DWP(-3,"edi"));	# num=num-1 to assist modulo-scheduling
+	#&mov	($_num,$num);		# redundant as $num is not reused
+	&mov	($_sp,"ebp");		# saved stack pointer!
+
+if($sse2) {
+$acc0="mm0";	# mmx register bank layout
+$acc1="mm1";
+$car0="mm2";
+$car1="mm3";
+$mul0="mm4";
+$mul1="mm5";
+$temp="mm6";
+$mask="mm7";
+
+	&picmeup("eax","OPENSSL_ia32cap_P");
+	&bt	(&DWP(0,"eax"),26);
+	&jnc	(&label("non_sse2"));
+
+	&mov	("eax",-1);
+	&movd	($mask,"eax");		# mask 32 lower bits
+
+	&mov	($ap,$_ap);		# load input pointers
+	&mov	($bp,$_bp);
+	&mov	($np,$_np);
+
+	&xor	($i,$i);		# i=0
+	&xor	($j,$j);		# j=0
+
+	&movd	($mul0,&DWP(0,$bp));		# bp[0]
+	&movd	($mul1,&DWP(0,$ap));		# ap[0]
+	&movd	($car1,&DWP(0,$np));		# np[0]
+
+	&pmuludq($mul1,$mul0);			# ap[0]*bp[0]
+	&movq	($car0,$mul1);
+	&movq	($acc0,$mul1);			# I wish movd worked for
+	&pand	($acc0,$mask);			# inter-register transfers
+
+	&pmuludq($mul1,$_n0q);			# *=n0
+
+	&pmuludq($car1,$mul1);			# "t[0]"*np[0]*n0
+	&paddq	($car1,$acc0);
+
+	&movd	($acc1,&DWP(4,$np));		# np[1]
+	&movd	($acc0,&DWP(4,$ap));		# ap[1]
+
+	&psrlq	($car0,32);
+	&psrlq	($car1,32);
+
+	&inc	($j);				# j++
+&set_label("1st",16);
+	&pmuludq($acc0,$mul0);			# ap[j]*bp[0]
+	&pmuludq($acc1,$mul1);			# np[j]*m1
+	&paddq	($car0,$acc0);			# +=c0
+	&paddq	($car1,$acc1);			# +=c1
+
+	&movq	($acc0,$car0);
+	&pand	($acc0,$mask);
+	&movd	($acc1,&DWP(4,$np,$j,4));	# np[j+1]
+	&paddq	($car1,$acc0);			# +=ap[j]*bp[0];
+	&movd	($acc0,&DWP(4,$ap,$j,4));	# ap[j+1]
+	&psrlq	($car0,32);
+	&movd	(&DWP($frame-4,"esp",$j,4),$car1);	# tp[j-1]=
+	&psrlq	($car1,32);
+
+	&lea	($j,&DWP(1,$j));
+	&cmp	($j,$num);
+	&jl	(&label("1st"));
+
+	&pmuludq($acc0,$mul0);			# ap[num-1]*bp[0]
+	&pmuludq($acc1,$mul1);			# np[num-1]*m1
+	&paddq	($car0,$acc0);			# +=c0
+	&paddq	($car1,$acc1);			# +=c1
+
+	&movq	($acc0,$car0);
+	&pand	($acc0,$mask);
+	&paddq	($car1,$acc0);			# +=ap[num-1]*bp[0];
+	&movd	(&DWP($frame-4,"esp",$j,4),$car1);	# tp[num-2]=
+
+	&psrlq	($car0,32);
+	&psrlq	($car1,32);
+
+	&paddq	($car1,$car0);
+	&movq	(&QWP($frame,"esp",$num,4),$car1);	# tp[num].tp[num-1]
+
+	&inc	($i);				# i++
+&set_label("outer");
+	&xor	($j,$j);			# j=0
+
+	&movd	($mul0,&DWP(0,$bp,$i,4));	# bp[i]
+	&movd	($mul1,&DWP(0,$ap));		# ap[0]
+	&movd	($temp,&DWP($frame,"esp"));	# tp[0]
+	&movd	($car1,&DWP(0,$np));		# np[0]
+	&pmuludq($mul1,$mul0);			# ap[0]*bp[i]
+
+	&paddq	($mul1,$temp);			# +=tp[0]
+	&movq	($acc0,$mul1);
+	&movq	($car0,$mul1);
+	&pand	($acc0,$mask);
+
+	&pmuludq($mul1,$_n0q);			# *=n0
+
+	&pmuludq($car1,$mul1);
+	&paddq	($car1,$acc0);
+
+	&movd	($temp,&DWP($frame+4,"esp"));	# tp[1]
+	&movd	($acc1,&DWP(4,$np));		# np[1]
+	&movd	($acc0,&DWP(4,$ap));		# ap[1]
+
+	&psrlq	($car0,32);
+	&psrlq	($car1,32);
+	&paddq	($car0,$temp);			# +=tp[1]
+
+	&inc	($j);				# j++
+	&dec	($num);
+&set_label("inner");
+	&pmuludq($acc0,$mul0);			# ap[j]*bp[i]
+	&pmuludq($acc1,$mul1);			# np[j]*m1
+	&paddq	($car0,$acc0);			# +=c0
+	&paddq	($car1,$acc1);			# +=c1
+
+	&movq	($acc0,$car0);
+	&movd	($temp,&DWP($frame+4,"esp",$j,4));# tp[j+1]
+	&pand	($acc0,$mask);
+	&movd	($acc1,&DWP(4,$np,$j,4));	# np[j+1]
+	&paddq	($car1,$acc0);			# +=ap[j]*bp[i]+tp[j]
+	&movd	($acc0,&DWP(4,$ap,$j,4));	# ap[j+1]
+	&psrlq	($car0,32);
+	&movd	(&DWP($frame-4,"esp",$j,4),$car1);# tp[j-1]=
+	&psrlq	($car1,32);
+	&paddq	($car0,$temp);			# +=tp[j+1]
+
+	&dec	($num);
+	&lea	($j,&DWP(1,$j));		# j++
+	&jnz	(&label("inner"));
+
+	&mov	($num,$j);
+	&pmuludq($acc0,$mul0);			# ap[num-1]*bp[i]
+	&pmuludq($acc1,$mul1);			# np[num-1]*m1
+	&paddq	($car0,$acc0);			# +=c0
+	&paddq	($car1,$acc1);			# +=c1
+
+	&movq	($acc0,$car0);
+	&pand	($acc0,$mask);
+	&paddq	($car1,$acc0);			# +=ap[num-1]*bp[i]+tp[num-1]
+	&movd	(&DWP($frame-4,"esp",$j,4),$car1);	# tp[num-2]=
+	&psrlq	($car0,32);
+	&psrlq	($car1,32);
+
+	&movd	($temp,&DWP($frame+4,"esp",$num,4));	# += tp[num]
+	&paddq	($car1,$car0);
+	&paddq	($car1,$temp);
+	&movq	(&QWP($frame,"esp",$num,4),$car1);	# tp[num].tp[num-1]
+
+	&lea	($i,&DWP(1,$i));		# i++
+	&cmp	($i,$num);
+	&jle	(&label("outer"));
+
+	&emms	();				# done with mmx bank
+	&jmp	(&label("common_tail"));
+
+&set_label("non_sse2",16);
+}
+
+if (0) {
+	&mov	("esp",$_sp);
+	&xor	("eax","eax");	# signal "not fast enough [yet]"
+	&jmp	(&label("just_leave"));
+	# While the below code provides competitive performance for
+	# all key lengthes on modern Intel cores, it's still more
+	# than 10% slower for 4096-bit key elsewhere:-( "Competitive"
+	# means compared to the original integer-only assembler.
+	# 512-bit RSA sign is better by ~40%, but that's about all
+	# one can say about all CPUs...
+} else {
+$inp="esi";	# integer path uses these registers differently
+$word="edi";
+$carry="ebp";
+
+	&mov	($inp,$_ap);
+	&lea	($carry,&DWP(1,$num));
+	&mov	($word,$_bp);
+	&xor	($j,$j);				# j=0
+	&mov	("edx",$inp);
+	&and	($carry,1);				# see if num is even
+	&sub	("edx",$word);				# see if ap==bp
+	&lea	("eax",&DWP(4,$word,$num,4));		# &bp[num]
+	&or	($carry,"edx");
+	&mov	($word,&DWP(0,$word));			# bp[0]
+	&jz	(&label("bn_sqr_mont"));
+	&mov	($_bpend,"eax");
+	&mov	("eax",&DWP(0,$inp));
+	&xor	("edx","edx");
+
+&set_label("mull",16);
+	&mov	($carry,"edx");
+	&mul	($word);				# ap[j]*bp[0]
+	&add	($carry,"eax");
+	&lea	($j,&DWP(1,$j));
+	&adc	("edx",0);
+	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[j+1]
+	&cmp	($j,$num);
+	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j]=
+	&jl	(&label("mull"));
+
+	&mov	($carry,"edx");
+	&mul	($word);				# ap[num-1]*bp[0]
+	 &mov	($word,$_n0);
+	&add	("eax",$carry);
+	 &mov	($inp,$_np);
+	&adc	("edx",0);
+	 &imul	($word,&DWP($frame,"esp"));		# n0*tp[0]
+
+	&mov	(&DWP($frame,"esp",$num,4),"eax");	# tp[num-1]=
+	&xor	($j,$j);
+	&mov	(&DWP($frame+4,"esp",$num,4),"edx");	# tp[num]=
+	&mov	(&DWP($frame+8,"esp",$num,4),$j);	# tp[num+1]=
+
+	&mov	("eax",&DWP(0,$inp));			# np[0]
+	&mul	($word);				# np[0]*m
+	&add	("eax",&DWP($frame,"esp"));		# +=tp[0]
+	&mov	("eax",&DWP(4,$inp));			# np[1]
+	&adc	("edx",0);
+	&inc	($j);
+
+	&jmp	(&label("2ndmadd"));
+
+&set_label("1stmadd",16);
+	&mov	($carry,"edx");
+	&mul	($word);				# ap[j]*bp[i]
+	&add	($carry,&DWP($frame,"esp",$j,4));	# +=tp[j]
+	&lea	($j,&DWP(1,$j));
+	&adc	("edx",0);
+	&add	($carry,"eax");
+	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[j+1]
+	&adc	("edx",0);
+	&cmp	($j,$num);
+	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j]=
+	&jl	(&label("1stmadd"));
+
+	&mov	($carry,"edx");
+	&mul	($word);				# ap[num-1]*bp[i]
+	&add	("eax",&DWP($frame,"esp",$num,4));	# +=tp[num-1]
+	 &mov	($word,$_n0);
+	&adc	("edx",0);
+	 &mov	($inp,$_np);
+	&add	($carry,"eax");
+	&adc	("edx",0);
+	 &imul	($word,&DWP($frame,"esp"));		# n0*tp[0]
+
+	&xor	($j,$j);
+	&add	("edx",&DWP($frame+4,"esp",$num,4));	# carry+=tp[num]
+	&mov	(&DWP($frame,"esp",$num,4),$carry);	# tp[num-1]=
+	&adc	($j,0);
+	 &mov	("eax",&DWP(0,$inp));			# np[0]
+	&mov	(&DWP($frame+4,"esp",$num,4),"edx");	# tp[num]=
+	&mov	(&DWP($frame+8,"esp",$num,4),$j);	# tp[num+1]=
+
+	&mul	($word);				# np[0]*m
+	&add	("eax",&DWP($frame,"esp"));		# +=tp[0]
+	&mov	("eax",&DWP(4,$inp));			# np[1]
+	&adc	("edx",0);
+	&mov	($j,1);
+
+&set_label("2ndmadd",16);
+	&mov	($carry,"edx");
+	&mul	($word);				# np[j]*m
+	&add	($carry,&DWP($frame,"esp",$j,4));	# +=tp[j]
+	&lea	($j,&DWP(1,$j));
+	&adc	("edx",0);
+	&add	($carry,"eax");
+	&mov	("eax",&DWP(0,$inp,$j,4));		# np[j+1]
+	&adc	("edx",0);
+	&cmp	($j,$num);
+	&mov	(&DWP($frame-8,"esp",$j,4),$carry);	# tp[j-1]=
+	&jl	(&label("2ndmadd"));
+
+	&mov	($carry,"edx");
+	&mul	($word);				# np[j]*m
+	&add	($carry,&DWP($frame,"esp",$num,4));	# +=tp[num-1]
+	&adc	("edx",0);
+	&add	($carry,"eax");
+	&adc	("edx",0);
+	&mov	(&DWP($frame-4,"esp",$num,4),$carry);	# tp[num-2]=
+
+	&xor	("eax","eax");
+	 &mov	($j,$_bp);				# &bp[i]
+	&add	("edx",&DWP($frame+4,"esp",$num,4));	# carry+=tp[num]
+	&adc	("eax",&DWP($frame+8,"esp",$num,4));	# +=tp[num+1]
+	 &lea	($j,&DWP(4,$j));
+	&mov	(&DWP($frame,"esp",$num,4),"edx");	# tp[num-1]=
+	 &cmp	($j,$_bpend);
+	&mov	(&DWP($frame+4,"esp",$num,4),"eax");	# tp[num]=
+	&je	(&label("common_tail"));
+
+	&mov	($word,&DWP(0,$j));			# bp[i+1]
+	&mov	($inp,$_ap);
+	&mov	($_bp,$j);				# &bp[++i]
+	&xor	($j,$j);
+	&xor	("edx","edx");
+	&mov	("eax",&DWP(0,$inp));
+	&jmp	(&label("1stmadd"));
+
+&set_label("bn_sqr_mont",16);
+$sbit=$num;
+	&mov	($_num,$num);
+	&mov	($_bp,$j);				# i=0
+
+	&mov	("eax",$word);				# ap[0]
+	&mul	($word);				# ap[0]*ap[0]
+	&mov	(&DWP($frame,"esp"),"eax");		# tp[0]=
+	&mov	($sbit,"edx");
+	&shr	("edx",1);
+	&and	($sbit,1);
+	&inc	($j);
+&set_label("sqr",16);
+	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[j]
+	&mov	($carry,"edx");
+	&mul	($word);				# ap[j]*ap[0]
+	&add	("eax",$carry);
+	&lea	($j,&DWP(1,$j));
+	&adc	("edx",0);
+	&lea	($carry,&DWP(0,$sbit,"eax",2));
+	&shr	("eax",31);
+	&cmp	($j,$_num);
+	&mov	($sbit,"eax");
+	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j]=
+	&jl	(&label("sqr"));
+
+	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[num-1]
+	&mov	($carry,"edx");
+	&mul	($word);				# ap[num-1]*ap[0]
+	&add	("eax",$carry);
+	 &mov	($word,$_n0);
+	&adc	("edx",0);
+	 &mov	($inp,$_np);
+	&lea	($carry,&DWP(0,$sbit,"eax",2));
+	 &imul	($word,&DWP($frame,"esp"));		# n0*tp[0]
+	&shr	("eax",31);
+	&mov	(&DWP($frame,"esp",$j,4),$carry);	# tp[num-1]=
+
+	&lea	($carry,&DWP(0,"eax","edx",2));
+	 &mov	("eax",&DWP(0,$inp));			# np[0]
+	&shr	("edx",31);
+	&mov	(&DWP($frame+4,"esp",$j,4),$carry);	# tp[num]=
+	&mov	(&DWP($frame+8,"esp",$j,4),"edx");	# tp[num+1]=
+
+	&mul	($word);				# np[0]*m
+	&add	("eax",&DWP($frame,"esp"));		# +=tp[0]
+	&mov	($num,$j);
+	&adc	("edx",0);
+	&mov	("eax",&DWP(4,$inp));			# np[1]
+	&mov	($j,1);
+
+&set_label("3rdmadd",16);
+	&mov	($carry,"edx");
+	&mul	($word);				# np[j]*m
+	&add	($carry,&DWP($frame,"esp",$j,4));	# +=tp[j]
+	&adc	("edx",0);
+	&add	($carry,"eax");
+	&mov	("eax",&DWP(4,$inp,$j,4));		# np[j+1]
+	&adc	("edx",0);
+	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j-1]=
+
+	&mov	($carry,"edx");
+	&mul	($word);				# np[j+1]*m
+	&add	($carry,&DWP($frame+4,"esp",$j,4));	# +=tp[j+1]
+	&lea	($j,&DWP(2,$j));
+	&adc	("edx",0);
+	&add	($carry,"eax");
+	&mov	("eax",&DWP(0,$inp,$j,4));		# np[j+2]
+	&adc	("edx",0);
+	&cmp	($j,$num);
+	&mov	(&DWP($frame-8,"esp",$j,4),$carry);	# tp[j]=
+	&jl	(&label("3rdmadd"));
+
+	&mov	($carry,"edx");
+	&mul	($word);				# np[j]*m
+	&add	($carry,&DWP($frame,"esp",$num,4));	# +=tp[num-1]
+	&adc	("edx",0);
+	&add	($carry,"eax");
+	&adc	("edx",0);
+	&mov	(&DWP($frame-4,"esp",$num,4),$carry);	# tp[num-2]=
+
+	&mov	($j,$_bp);				# i
+	&xor	("eax","eax");
+	&mov	($inp,$_ap);
+	&add	("edx",&DWP($frame+4,"esp",$num,4));	# carry+=tp[num]
+	&adc	("eax",&DWP($frame+8,"esp",$num,4));	# +=tp[num+1]
+	&mov	(&DWP($frame,"esp",$num,4),"edx");	# tp[num-1]=
+	&cmp	($j,$num);
+	&mov	(&DWP($frame+4,"esp",$num,4),"eax");	# tp[num]=
+	&je	(&label("common_tail"));
+
+	&mov	($word,&DWP(4,$inp,$j,4));		# ap[i]
+	&lea	($j,&DWP(1,$j));
+	&mov	("eax",$word);
+	&mov	($_bp,$j);				# ++i
+	&mul	($word);				# ap[i]*ap[i]
+	&add	("eax",&DWP($frame,"esp",$j,4));	# +=tp[i]
+	&adc	("edx",0);
+	&mov	(&DWP($frame,"esp",$j,4),"eax");	# tp[i]=
+	&xor	($carry,$carry);
+	&cmp	($j,$num);
+	&lea	($j,&DWP(1,$j));
+	&je	(&label("sqrlast"));
+
+	&mov	($sbit,"edx");				# zaps $num
+	&shr	("edx",1);
+	&and	($sbit,1);
+&set_label("sqradd",16);
+	&mov	("eax",&DWP(0,$inp,$j,4));		# ap[j]
+	&mov	($carry,"edx");
+	&mul	($word);				# ap[j]*ap[i]
+	&add	("eax",$carry);
+	&lea	($carry,&DWP(0,"eax","eax"));
+	&adc	("edx",0);
+	&shr	("eax",31);
+	&add	($carry,&DWP($frame,"esp",$j,4));	# +=tp[j]
+	&lea	($j,&DWP(1,$j));
+	&adc	("eax",0);
+	&add	($carry,$sbit);
+	&adc	("eax",0);
+	&cmp	($j,$_num);
+	&mov	(&DWP($frame-4,"esp",$j,4),$carry);	# tp[j]=
+	&mov	($sbit,"eax");
+	&jle	(&label("sqradd"));
+
+	&mov	($carry,"edx");
+	&lea	("edx",&DWP(0,$sbit,"edx",2));
+	&shr	($carry,31);
+&set_label("sqrlast");
+	&mov	($word,$_n0);
+	&mov	($inp,$_np);
+	&imul	($word,&DWP($frame,"esp"));		# n0*tp[0]
+
+	&add	("edx",&DWP($frame,"esp",$j,4));	# +=tp[num]
+	&mov	("eax",&DWP(0,$inp));			# np[0]
+	&adc	($carry,0);
+	&mov	(&DWP($frame,"esp",$j,4),"edx");	# tp[num]=
+	&mov	(&DWP($frame+4,"esp",$j,4),$carry);	# tp[num+1]=
+
+	&mul	($word);				# np[0]*m
+	&add	("eax",&DWP($frame,"esp"));		# +=tp[0]
+	&lea	($num,&DWP(-1,$j));
+	&adc	("edx",0);
+	&mov	($j,1);
+	&mov	("eax",&DWP(4,$inp));			# np[1]
+
+	&jmp	(&label("3rdmadd"));
+}
+
+&set_label("common_tail",16);
+	&mov	($np,$_np);			# load modulus pointer
+	&mov	($rp,$_rp);			# load result pointer
+	&lea	($tp,&DWP($frame,"esp"));	# [$ap and $bp are zapped]
+
+	&mov	("eax",&DWP(0,$tp));		# tp[0]
+	&mov	($j,$num);			# j=num-1
+	&xor	($i,$i);			# i=0 and clear CF!
+
+&set_label("sub",16);
+	&sbb	("eax",&DWP(0,$np,$i,4));
+	&mov	(&DWP(0,$rp,$i,4),"eax");	# rp[i]=tp[i]-np[i]
+	&dec	($j);				# doesn't affect CF!
+	&mov	("eax",&DWP(4,$tp,$i,4));	# tp[i+1]
+	&lea	($i,&DWP(1,$i));		# i++
+	&jge	(&label("sub"));
+
+	&sbb	("eax",0);			# handle upmost overflow bit
+	&and	($tp,"eax");
+	&not	("eax");
+	&mov	($np,$rp);
+	&and	($np,"eax");
+	&or	($tp,$np);			# tp=carry?tp:rp
+
+&set_label("copy",16);				# copy or in-place refresh
+	&mov	("eax",&DWP(0,$tp,$num,4));
+	&mov	(&DWP(0,$rp,$num,4),"eax");	# rp[i]=tp[i]
+	&mov	(&DWP($frame,"esp",$num,4),$j);	# zap temporary vector
+	&dec	($num);
+	&jge	(&label("copy"));
+
+	&mov	("esp",$_sp);		# pull saved stack pointer
+	&mov	("eax",1);
+&set_label("just_leave");
+&function_end("bn_mul_mont");
+
+&asciz("Montgomery Multiplication for x86, CRYPTOGAMS by <appro\@openssl.org>");
+
+&asm_finish();
diff --git a/crypto/bn/asm/x86_64-mont.pl b/crypto/bn/asm/x86_64-mont.pl
old mode 100644
new mode 100755
diff --git a/crypto/bn/bn.h b/crypto/bn/bn.h
index 6d754d5..f1719a5 100644
--- a/crypto/bn/bn.h
+++ b/crypto/bn/bn.h
@@ -408,8 +408,8 @@
 void	BN_CTX_end(BN_CTX *ctx);
 int     BN_rand(BIGNUM *rnd, int bits, int top,int bottom);
 int     BN_pseudo_rand(BIGNUM *rnd, int bits, int top,int bottom);
-int	BN_rand_range(BIGNUM *rnd, BIGNUM *range);
-int	BN_pseudo_rand_range(BIGNUM *rnd, BIGNUM *range);
+int	BN_rand_range(BIGNUM *rnd, const BIGNUM *range);
+int	BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range);
 int	BN_num_bits(const BIGNUM *a);
 int	BN_num_bits_word(BN_ULONG);
 BIGNUM *BN_new(void);
@@ -531,6 +531,17 @@
 int	BN_is_prime_fasttest_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx,
 		int do_trial_division, BN_GENCB *cb);
 
+int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx);
+
+int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+			const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2,
+			const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb);
+int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+			BIGNUM *Xp1, BIGNUM *Xp2,
+			const BIGNUM *Xp,
+			const BIGNUM *e, BN_CTX *ctx,
+			BN_GENCB *cb);
+
 BN_MONT_CTX *BN_MONT_CTX_new(void );
 void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
 int BN_mod_mul_montgomery(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,
diff --git a/crypto/bn/bn_div.c b/crypto/bn/bn_div.c
index 8655eb1..1e8e576 100644
--- a/crypto/bn/bn_div.c
+++ b/crypto/bn/bn_div.c
@@ -187,6 +187,17 @@
 	BN_ULONG d0,d1;
 	int num_n,div_n;
 
+	/* Invalid zero-padding would have particularly bad consequences
+	 * in the case of 'num', so don't just rely on bn_check_top() for this one
+	 * (bn_check_top() works only for BN_DEBUG builds) */
+	if (num->top > 0 && num->d[num->top - 1] == 0)
+		{
+		BNerr(BN_F_BN_DIV,BN_R_NOT_INITIALIZED);
+		return 0;
+		}
+
+	bn_check_top(num);
+
 	if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0) || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0))
 		{
 		return BN_div_no_branch(dv, rm, num, divisor, ctx);
@@ -194,7 +205,7 @@
 
 	bn_check_top(dv);
 	bn_check_top(rm);
-	bn_check_top(num);
+	/* bn_check_top(num); */ /* 'num' has been checked already */
 	bn_check_top(divisor);
 
 	if (BN_is_zero(divisor))
@@ -419,7 +430,7 @@
 
 	bn_check_top(dv);
 	bn_check_top(rm);
-	bn_check_top(num);
+	/* bn_check_top(num); */ /* 'num' has been checked in BN_div() */
 	bn_check_top(divisor);
 
 	if (BN_is_zero(divisor))
diff --git a/crypto/bn/bn_gf2m.c b/crypto/bn/bn_gf2m.c
index 6a79385..306f029 100644
--- a/crypto/bn/bn_gf2m.c
+++ b/crypto/bn/bn_gf2m.c
@@ -384,7 +384,11 @@
 		if (zz == 0) break;
 		d1 = BN_BITS2 - d0;
 		
-		if (d0) z[dN] = (z[dN] << d1) >> d1; /* clear up the top d1 bits */
+		/* clear up the top d1 bits */
+		if (d0)
+			z[dN] = (z[dN] << d1) >> d1;
+		else
+			z[dN] = 0;
 		z[0] ^= zz; /* reduction t^0 component */
 
 		for (k = 1; p[k] != 0; k++)
diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c
index 2649b8c..32a8fba 100644
--- a/crypto/bn/bn_lib.c
+++ b/crypto/bn/bn_lib.c
@@ -139,25 +139,6 @@
 	return(&const_one);
 	}
 
-char *BN_options(void)
-	{
-	static int init=0;
-	static char data[16];
-
-	if (!init)
-		{
-		init++;
-#ifdef BN_LLONG
-		BIO_snprintf(data,sizeof data,"bn(%d,%d)",
-			     (int)sizeof(BN_ULLONG)*8,(int)sizeof(BN_ULONG)*8);
-#else
-		BIO_snprintf(data,sizeof data,"bn(%d,%d)",
-			     (int)sizeof(BN_ULONG)*8,(int)sizeof(BN_ULONG)*8);
-#endif
-		}
-	return(data);
-	}
-
 int BN_num_bits_word(BN_ULONG l)
 	{
 	static const char bits[256]={
diff --git a/crypto/bn/bn_nist.c b/crypto/bn/bn_nist.c
index e14232f..2ca5b01 100644
--- a/crypto/bn/bn_nist.c
+++ b/crypto/bn/bn_nist.c
@@ -59,109 +59,266 @@
 #include "bn_lcl.h"
 #include "cryptlib.h"
 
+
 #define BN_NIST_192_TOP	(192+BN_BITS2-1)/BN_BITS2
 #define BN_NIST_224_TOP	(224+BN_BITS2-1)/BN_BITS2
 #define BN_NIST_256_TOP	(256+BN_BITS2-1)/BN_BITS2
 #define BN_NIST_384_TOP	(384+BN_BITS2-1)/BN_BITS2
 #define BN_NIST_521_TOP	(521+BN_BITS2-1)/BN_BITS2
 
+/* pre-computed tables are "carry-less" values of modulus*(i+1) */
 #if BN_BITS2 == 64
-static const BN_ULONG _nist_p_192[] =
-	{0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFEULL,
-	0xFFFFFFFFFFFFFFFFULL};
-static const BN_ULONG _nist_p_224[] =
+static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
+	{0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFFULL},
+	{0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFDULL,0xFFFFFFFFFFFFFFFFULL},
+	{0xFFFFFFFFFFFFFFFDULL,0xFFFFFFFFFFFFFFFCULL,0xFFFFFFFFFFFFFFFFULL}
+	};
+static const BN_ULONG _nist_p_192_sqr[] = {
+	0x0000000000000001ULL,0x0000000000000002ULL,0x0000000000000001ULL,
+	0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFDULL,0xFFFFFFFFFFFFFFFFULL
+	};
+static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
 	{0x0000000000000001ULL,0xFFFFFFFF00000000ULL,
-	0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL};
-static const BN_ULONG _nist_p_256[] =
+	 0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL},
+	{0x0000000000000002ULL,0xFFFFFFFE00000000ULL,
+	 0xFFFFFFFFFFFFFFFFULL,0x00000001FFFFFFFFULL} /* this one is "carry-full" */
+	};
+static const BN_ULONG _nist_p_224_sqr[] = {
+	0x0000000000000001ULL,0xFFFFFFFE00000000ULL,
+	0xFFFFFFFFFFFFFFFFULL,0x0000000200000000ULL,
+	0x0000000000000000ULL,0xFFFFFFFFFFFFFFFEULL,
+	0xFFFFFFFFFFFFFFFFULL
+	};
+static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
 	{0xFFFFFFFFFFFFFFFFULL,0x00000000FFFFFFFFULL,
-	0x0000000000000000ULL,0xFFFFFFFF00000001ULL};
-static const BN_ULONG _nist_p_384[] =
-	{0x00000000FFFFFFFFULL,0xFFFFFFFF00000000ULL,
-	0xFFFFFFFFFFFFFFFEULL,0xFFFFFFFFFFFFFFFFULL,
-	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL};
+	 0x0000000000000000ULL,0xFFFFFFFF00000001ULL},
+	{0xFFFFFFFFFFFFFFFEULL,0x00000001FFFFFFFFULL,
+	 0x0000000000000000ULL,0xFFFFFFFE00000002ULL},
+	{0xFFFFFFFFFFFFFFFDULL,0x00000002FFFFFFFFULL,
+	 0x0000000000000000ULL,0xFFFFFFFD00000003ULL},
+	{0xFFFFFFFFFFFFFFFCULL,0x00000003FFFFFFFFULL,
+	 0x0000000000000000ULL,0xFFFFFFFC00000004ULL},
+	{0xFFFFFFFFFFFFFFFBULL,0x00000004FFFFFFFFULL,
+	 0x0000000000000000ULL,0xFFFFFFFB00000005ULL},
+	};
+static const BN_ULONG _nist_p_256_sqr[] = {
+	0x0000000000000001ULL,0xFFFFFFFE00000000ULL,
+	0xFFFFFFFFFFFFFFFFULL,0x00000001FFFFFFFEULL,
+	0x00000001FFFFFFFEULL,0x00000001FFFFFFFEULL,
+	0xFFFFFFFE00000001ULL,0xFFFFFFFE00000002ULL
+	};
+static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
+	{0x00000000FFFFFFFFULL,0xFFFFFFFF00000000ULL,0xFFFFFFFFFFFFFFFEULL,
+	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
+	{0x00000001FFFFFFFEULL,0xFFFFFFFE00000000ULL,0xFFFFFFFFFFFFFFFDULL,
+	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
+	{0x00000002FFFFFFFDULL,0xFFFFFFFD00000000ULL,0xFFFFFFFFFFFFFFFCULL,
+	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
+	{0x00000003FFFFFFFCULL,0xFFFFFFFC00000000ULL,0xFFFFFFFFFFFFFFFBULL,
+	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
+	{0x00000004FFFFFFFBULL,0xFFFFFFFB00000000ULL,0xFFFFFFFFFFFFFFFAULL,
+	 0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL},
+	};
+static const BN_ULONG _nist_p_384_sqr[] = {
+	0xFFFFFFFE00000001ULL,0x0000000200000000ULL,0xFFFFFFFE00000000ULL,
+	0x0000000200000000ULL,0x0000000000000001ULL,0x0000000000000000ULL,
+	0x00000001FFFFFFFEULL,0xFFFFFFFE00000000ULL,0xFFFFFFFFFFFFFFFDULL,
+	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL
+	};
 static const BN_ULONG _nist_p_521[] =
 	{0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
 	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
 	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
 	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
 	0x00000000000001FFULL};
+static const BN_ULONG _nist_p_521_sqr[] = {
+	0x0000000000000001ULL,0x0000000000000000ULL,0x0000000000000000ULL,
+	0x0000000000000000ULL,0x0000000000000000ULL,0x0000000000000000ULL,
+	0x0000000000000000ULL,0x0000000000000000ULL,0xFFFFFFFFFFFFFC00ULL,
+	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
+	0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,0xFFFFFFFFFFFFFFFFULL,
+	0xFFFFFFFFFFFFFFFFULL,0x000000000003FFFFULL
+	};
 #elif BN_BITS2 == 32
-static const BN_ULONG _nist_p_192[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,
-	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
-static const BN_ULONG _nist_p_224[] = {0x00000001,0x00000000,0x00000000,
-	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
-static const BN_ULONG _nist_p_256[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-	0x00000000,0x00000000,0x00000000,0x00000001,0xFFFFFFFF};
-static const BN_ULONG _nist_p_384[] = {0xFFFFFFFF,0x00000000,0x00000000,
-	0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
-	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
+static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = {
+	{0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+	{0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+	{0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFC,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}
+	};
+static const BN_ULONG _nist_p_192_sqr[] = {
+	0x00000001,0x00000000,0x00000002,0x00000000,0x00000001,0x00000000,
+	0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF
+	};
+static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = {
+	{0x00000001,0x00000000,0x00000000,0xFFFFFFFF,
+	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+	{0x00000002,0x00000000,0x00000000,0xFFFFFFFE,
+	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}
+	};
+static const BN_ULONG _nist_p_224_sqr[] = {
+	0x00000001,0x00000000,0x00000000,0xFFFFFFFE,
+	0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000002,
+	0x00000000,0x00000000,0xFFFFFFFE,0xFFFFFFFF,
+	0xFFFFFFFF,0xFFFFFFFF
+	};
+static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = {
+	{0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000,
+	 0x00000000,0x00000000,0x00000001,0xFFFFFFFF},
+	{0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0x00000001,
+	 0x00000000,0x00000000,0x00000002,0xFFFFFFFE},
+	{0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFF,0x00000002,
+	 0x00000000,0x00000000,0x00000003,0xFFFFFFFD},
+	{0xFFFFFFFC,0xFFFFFFFF,0xFFFFFFFF,0x00000003,
+	 0x00000000,0x00000000,0x00000004,0xFFFFFFFC},
+	{0xFFFFFFFB,0xFFFFFFFF,0xFFFFFFFF,0x00000004,
+	 0x00000000,0x00000000,0x00000005,0xFFFFFFFB},
+	};
+static const BN_ULONG _nist_p_256_sqr[] = {
+	0x00000001,0x00000000,0x00000000,0xFFFFFFFE,
+	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,0x00000001,
+	0xFFFFFFFE,0x00000001,0xFFFFFFFE,0x00000001,
+	0x00000001,0xFFFFFFFE,0x00000002,0xFFFFFFFE
+	};
+static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = {
+	{0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,
+	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+	{0xFFFFFFFE,0x00000001,0x00000000,0xFFFFFFFE,0xFFFFFFFD,0xFFFFFFFF,
+	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+	{0xFFFFFFFD,0x00000002,0x00000000,0xFFFFFFFD,0xFFFFFFFC,0xFFFFFFFF,
+	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+	{0xFFFFFFFC,0x00000003,0x00000000,0xFFFFFFFC,0xFFFFFFFB,0xFFFFFFFF,
+	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+	{0xFFFFFFFB,0x00000004,0x00000000,0xFFFFFFFB,0xFFFFFFFA,0xFFFFFFFF,
+	 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+	};
+static const BN_ULONG _nist_p_384_sqr[] = {
+	0x00000001,0xFFFFFFFE,0x00000000,0x00000002,0x00000000,0xFFFFFFFE,
+	0x00000000,0x00000002,0x00000001,0x00000000,0x00000000,0x00000000,
+	0xFFFFFFFE,0x00000001,0x00000000,0xFFFFFFFE,0xFFFFFFFD,0xFFFFFFFF,
+	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF
+	};
 static const BN_ULONG _nist_p_521[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
 	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
 	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
 	0xFFFFFFFF,0x000001FF};
+static const BN_ULONG _nist_p_521_sqr[] = {
+	0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+	0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+	0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFC00,0xFFFFFFFF,
+	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+	0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+	0xFFFFFFFF,0xFFFFFFFF,0x0003FFFF
+	};
+#else
+#error "unsupported BN_BITS2"
 #endif
 
+
+static const BIGNUM _bignum_nist_p_192 =
+	{
+	(BN_ULONG *)_nist_p_192[0],
+	BN_NIST_192_TOP,
+	BN_NIST_192_TOP,
+	0,
+	BN_FLG_STATIC_DATA
+	};
+
+static const BIGNUM _bignum_nist_p_224 =
+	{
+	(BN_ULONG *)_nist_p_224[0],
+	BN_NIST_224_TOP,
+	BN_NIST_224_TOP,
+	0,
+	BN_FLG_STATIC_DATA
+	};
+
+static const BIGNUM _bignum_nist_p_256 =
+	{
+	(BN_ULONG *)_nist_p_256[0],
+	BN_NIST_256_TOP,
+	BN_NIST_256_TOP,
+	0,
+	BN_FLG_STATIC_DATA
+	};
+
+static const BIGNUM _bignum_nist_p_384 =
+	{
+	(BN_ULONG *)_nist_p_384[0],
+	BN_NIST_384_TOP,
+	BN_NIST_384_TOP,
+	0,
+	BN_FLG_STATIC_DATA
+	};
+
+static const BIGNUM _bignum_nist_p_521 =
+	{
+	(BN_ULONG *)_nist_p_521,
+	BN_NIST_521_TOP,
+	BN_NIST_521_TOP,
+	0,
+	BN_FLG_STATIC_DATA
+	};
+
+
 const BIGNUM *BN_get0_nist_prime_192(void)
 	{
-	static BIGNUM const_nist_192 = { (BN_ULONG *)_nist_p_192,
-		BN_NIST_192_TOP, BN_NIST_192_TOP, 0, BN_FLG_STATIC_DATA };
-	return &const_nist_192;
+	return &_bignum_nist_p_192;
 	}
 
 const BIGNUM *BN_get0_nist_prime_224(void)
 	{
-	static BIGNUM const_nist_224 = { (BN_ULONG *)_nist_p_224,
-		BN_NIST_224_TOP, BN_NIST_224_TOP, 0, BN_FLG_STATIC_DATA };
-	return &const_nist_224;
+	return &_bignum_nist_p_224;
 	}
 
 const BIGNUM *BN_get0_nist_prime_256(void)
 	{
-	static BIGNUM const_nist_256 = { (BN_ULONG *)_nist_p_256,
-		BN_NIST_256_TOP, BN_NIST_256_TOP, 0, BN_FLG_STATIC_DATA };
-	return &const_nist_256;
+	return &_bignum_nist_p_256;
 	}
 
 const BIGNUM *BN_get0_nist_prime_384(void)
 	{
-	static BIGNUM const_nist_384 = { (BN_ULONG *)_nist_p_384,
-		BN_NIST_384_TOP, BN_NIST_384_TOP, 0, BN_FLG_STATIC_DATA };
-	return &const_nist_384;
+	return &_bignum_nist_p_384;
 	}
 
 const BIGNUM *BN_get0_nist_prime_521(void)
 	{
-	static BIGNUM const_nist_521 = { (BN_ULONG *)_nist_p_521,
-		BN_NIST_521_TOP, BN_NIST_521_TOP, 0, BN_FLG_STATIC_DATA };
-	return &const_nist_521;
+	return &_bignum_nist_p_521;
 	}
 
-#define BN_NIST_ADD_ONE(a)	while (!(*(a)=(*(a)+1)&BN_MASK2)) ++(a);
 
 static void nist_cp_bn_0(BN_ULONG *buf, BN_ULONG *a, int top, int max)
-        {
+	{
 	int i;
-        BN_ULONG *_tmp1 = (buf), *_tmp2 = (a);
-        for (i = (top); i != 0; i--)
-                *_tmp1++ = *_tmp2++;
-        for (i = (max) - (top); i != 0; i--)
-                *_tmp1++ = (BN_ULONG) 0;
-        }
+	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;
+	}
 
 static void nist_cp_bn(BN_ULONG *buf, BN_ULONG *a, int top)
-        { 
+	{ 
 	int i;
-        BN_ULONG *_tmp1 = (buf), *_tmp2 = (a);
-        for (i = (top); i != 0; i--)
-                *_tmp1++ = *_tmp2++;
-        }
+	BN_ULONG *_tmp1 = (buf), *_tmp2 = (a);
+	for (i = (top); i != 0; i--)
+		*_tmp1++ = *_tmp2++;
+	}
 
 #if BN_BITS2 == 64
 #define bn_cp_64(to, n, from, m)	(to)[n] = (m>=0)?((from)[m]):0;
 #define bn_64_set_0(to, n)		(to)[n] = (BN_ULONG)0;
-/* TBD */
-#define bn_cp_32(to, n, from, m)	(to)[n] = (m>=0)?((from)[m]):0;
-#define bn_32_set_0(to, n)		(to)[n] = (BN_ULONG)0;
+/*
+ * two following macros are implemented under assumption that they
+ * are called in a sequence with *ascending* n, i.e. as they are...
+ */
+#define bn_cp_32_naked(to, n, from, m)	(((n)&1)?(to[(n)/2]|=((m)&1)?(from[(m)/2]&BN_MASK2h):(from[(m)/2]<<32))\
+						:(to[(n)/2] =((m)&1)?(from[(m)/2]>>32):(from[(m)/2]&BN_MASK2l)))
+#define bn_32_set_0(to, n)		(((n)&1)?(to[(n)/2]&=BN_MASK2l):(to[(n)/2]=0));
+#define bn_cp_32(to,n,from,m)		((m)>=0)?bn_cp_32_naked(to,n,from,m):bn_32_set_0(to,n)
 #else
 #define bn_cp_64(to, n, from, m) \
 	{ \
@@ -182,9 +339,9 @@
 
 #define nist_set_192(to, from, a1, a2, a3) \
 	{ \
-	if (a3 != 0) bn_cp_64(to, 0, from, (a3) - 3) else bn_64_set_0(to, 0)\
+	bn_cp_64(to, 0, from, (a3) - 3) \
 	bn_cp_64(to, 1, from, (a2) - 3) \
-	if (a1 != 0) bn_cp_64(to, 2, from, (a1) - 3) else bn_64_set_0(to, 2)\
+	bn_cp_64(to, 2, from, (a1) - 3) \
 	}
 
 int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
@@ -198,6 +355,16 @@
 		 c_d[BN_NIST_192_TOP],
 		*res;
 	size_t   mask;
+	static const BIGNUM _bignum_nist_p_192_sqr = {
+		(BN_ULONG *)_nist_p_192_sqr,
+		sizeof(_nist_p_192_sqr)/sizeof(_nist_p_192_sqr[0]),
+		sizeof(_nist_p_192_sqr)/sizeof(_nist_p_192_sqr[0]),
+		0,BN_FLG_STATIC_DATA };
+
+	field = &_bignum_nist_p_192; /* just to make sure */
+
+ 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_192_sqr)>=0)
+		return BN_nnmod(r, a, field, ctx);
 
 	i = BN_ucmp(field, a);
 	if (i == 0)
@@ -208,9 +375,6 @@
 	else if (i > 0)
 		return (r == a) ? 1 : (BN_copy(r ,a) != NULL);
 
-	if (top == BN_NIST_192_TOP)
-		return BN_usub(r, a, field);
-
 	if (r != a)
 		{
 		if (!bn_wexpand(r, BN_NIST_192_TOP))
@@ -224,23 +388,26 @@
 	nist_cp_bn_0(buf, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP, BN_NIST_192_TOP);
 
 	nist_set_192(t_d, buf, 0, 3, 3);
-	carry = bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
-	mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_192,BN_NIST_192_TOP);
-	mask = ~mask | (0-(size_t)carry);
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));
-	
+	carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
 	nist_set_192(t_d, buf, 4, 4, 0);
-	carry = bn_add_words(r_d, res, t_d, BN_NIST_192_TOP);
-	mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_192,BN_NIST_192_TOP);
-	mask = ~mask | (0-(size_t)carry);
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));
-
+	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
 	nist_set_192(t_d, buf, 5, 5, 5)
-	carry = bn_add_words(r_d, res, t_d, BN_NIST_192_TOP);
-	mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_192,BN_NIST_192_TOP);
-	mask = ~mask | (0-(size_t)carry);
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));
+	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
 
+	if (carry > 0)
+		carry = (int)bn_sub_words(r_d,r_d,_nist_p_192[carry-1],BN_NIST_192_TOP);
+	else
+		carry = 1;
+
+	/*
+	 * we need 'if (carry==0 || result>=modulus) result-=modulus;'
+	 * as comparison implies subtraction, we can write
+	 * 'tmp=result-modulus; if (!carry || !borrow) result=tmp;'
+	 * this is what happens below, but without explicit if:-) a.
+	 */
+	mask  = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_192[0],BN_NIST_192_TOP);
+	mask &= 0-(size_t)carry;
+	res   = (BN_ULONG *)(((size_t)c_d&~mask) | ((size_t)r_d&mask));
 	nist_cp_bn(r_d, res, BN_NIST_192_TOP);
 	r->top = BN_NIST_192_TOP;
 	bn_correct_top(r);
@@ -248,21 +415,22 @@
 	return 1;
 	}
 
+typedef BN_ULONG (*bn_addsub_f)(BN_ULONG *,const BN_ULONG *,const BN_ULONG *,int);
+
 #define nist_set_224(to, from, a1, a2, a3, a4, a5, a6, a7) \
 	{ \
-	if (a7 != 0) bn_cp_32(to, 0, from, (a7) - 7) else bn_32_set_0(to, 0)\
-	if (a6 != 0) bn_cp_32(to, 1, from, (a6) - 7) else bn_32_set_0(to, 1)\
-	if (a5 != 0) bn_cp_32(to, 2, from, (a5) - 7) else bn_32_set_0(to, 2)\
-	if (a4 != 0) bn_cp_32(to, 3, from, (a4) - 7) else bn_32_set_0(to, 3)\
-	if (a3 != 0) bn_cp_32(to, 4, from, (a3) - 7) else bn_32_set_0(to, 4)\
-	if (a2 != 0) bn_cp_32(to, 5, from, (a2) - 7) else bn_32_set_0(to, 5)\
-	if (a1 != 0) bn_cp_32(to, 6, from, (a1) - 7) else bn_32_set_0(to, 6)\
+	bn_cp_32(to, 0, from, (a7) - 7) \
+	bn_cp_32(to, 1, from, (a6) - 7) \
+	bn_cp_32(to, 2, from, (a5) - 7) \
+	bn_cp_32(to, 3, from, (a4) - 7) \
+	bn_cp_32(to, 4, from, (a3) - 7) \
+	bn_cp_32(to, 5, from, (a2) - 7) \
+	bn_cp_32(to, 6, from, (a1) - 7) \
 	}
 
 int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
 	BN_CTX *ctx)
 	{
-#if BN_BITS2 == 32
 	int	top = a->top, i;
 	int	carry;
 	BN_ULONG *r_d, *a_d = a->d;
@@ -271,6 +439,18 @@
 		 c_d[BN_NIST_224_TOP],
 		*res;
 	size_t   mask;
+	union { bn_addsub_f f; size_t p; } u;
+	static const BIGNUM _bignum_nist_p_224_sqr = {
+		(BN_ULONG *)_nist_p_224_sqr,
+		sizeof(_nist_p_224_sqr)/sizeof(_nist_p_224_sqr[0]),
+		sizeof(_nist_p_224_sqr)/sizeof(_nist_p_224_sqr[0]),
+		0,BN_FLG_STATIC_DATA };
+
+
+	field = &_bignum_nist_p_224; /* just to make sure */
+
+ 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_224_sqr)>=0)
+		return BN_nnmod(r, a, field, ctx);
 
 	i = BN_ucmp(field, a);
 	if (i == 0)
@@ -281,9 +461,6 @@
 	else if (i > 0)
 		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
 
-	if (top == BN_NIST_224_TOP)
-		return BN_usub(r, a, field);
-
 	if (r != a)
 		{
 		if (!bn_wexpand(r, BN_NIST_224_TOP))
@@ -294,67 +471,77 @@
 	else
 		r_d = a_d;
 
+#if BN_BITS2==64
+	/* copy upper 256 bits of 448 bit number ... */
+	nist_cp_bn_0(t_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, t_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);
-
+#endif
 	nist_set_224(t_d, buf, 10, 9, 8, 7, 0, 0, 0);
-	carry = bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
-	mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_224,BN_NIST_224_TOP);
-	mask = ~mask | (0-(size_t)carry);
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));
-	
+	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);
-	carry = bn_add_words(r_d, res, t_d, BN_NIST_224_TOP);
-	mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_224,BN_NIST_224_TOP);
-	mask = ~mask | (0-(size_t)carry);
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));
-
+	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);
-#if BRANCH_FREE
-	carry = bn_sub_words(r_d, res, t_d, BN_NIST_224_TOP);
-	bn_add_words(c_d,r_d,_nist_p_224,BN_NIST_224_TOP);
-	mask = 0-(size_t)carry;
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));
-#else
-	if (bn_sub_words(r_d, res, t_d, BN_NIST_224_TOP))
-		bn_add_words(r_d,r_d,_nist_p_224,BN_NIST_224_TOP);
-#endif
+	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);
-#if BRANCH_FREE
-	carry = bn_sub_words(r_d, res, t_d, BN_NIST_224_TOP);
-	bn_add_words(c_d,r_d,_nist_p_224,BN_NIST_224_TOP);
-	mask = 0-(size_t)carry;
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));
+	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
 
-	nist_cp_bn(r_d, res, BN_NIST_224_TOP);
-#else
-	if (bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP))
-		bn_add_words(r_d,r_d,_nist_p_224,BN_NIST_224_TOP);
+#if BN_BITS2==64
+	carry = (int)(r_d[BN_NIST_224_TOP-1]>>32);
 #endif
+	u.f = bn_sub_words;
+	if (carry > 0)
+		{
+		carry = (int)bn_sub_words(r_d,r_d,_nist_p_224[carry-1],BN_NIST_224_TOP);
+#if BN_BITS2==64
+		carry=(int)(~(r_d[BN_NIST_224_TOP-1]>>32))&1;
+#endif
+		}
+	else if (carry < 0)
+		{
+		/* it's a bit more comlicated logic in this case.
+		 * if bn_add_words yields no carry, then result
+		 * has to be adjusted by unconditionally *adding*
+		 * the modulus. but if it does, then result has
+		 * to be compared to the modulus and conditionally
+		 * adjusted by *subtracting* the latter. */
+		carry = (int)bn_add_words(r_d,r_d,_nist_p_224[-carry-1],BN_NIST_224_TOP);
+		mask = 0-(size_t)carry;
+		u.p = ((size_t)bn_sub_words&mask) | ((size_t)bn_add_words&~mask);
+		}
+	else
+		carry = 1;
+
+	/* otherwise it's effectively same as in BN_nist_mod_192... */
+	mask  = 0-(size_t)(*u.f)(c_d,r_d,_nist_p_224[0],BN_NIST_224_TOP);
+	mask &= 0-(size_t)carry;
+	res   = (BN_ULONG *)(((size_t)c_d&~mask) | ((size_t)r_d&mask));
+	nist_cp_bn(r_d, res, BN_NIST_224_TOP);
 	r->top = BN_NIST_224_TOP;
 	bn_correct_top(r);
 
 	return 1;
-#else	/* BN_BITS!=32 */
-	return 0;
-#endif
 	}
 
 #define nist_set_256(to, from, a1, a2, a3, a4, a5, a6, a7, a8) \
 	{ \
-	if (a8 != 0) bn_cp_32(to, 0, from, (a8) - 8) else bn_32_set_0(to, 0)\
-	if (a7 != 0) bn_cp_32(to, 1, from, (a7) - 8) else bn_32_set_0(to, 1)\
-	if (a6 != 0) bn_cp_32(to, 2, from, (a6) - 8) else bn_32_set_0(to, 2)\
-	if (a5 != 0) bn_cp_32(to, 3, from, (a5) - 8) else bn_32_set_0(to, 3)\
-	if (a4 != 0) bn_cp_32(to, 4, from, (a4) - 8) else bn_32_set_0(to, 4)\
-	if (a3 != 0) bn_cp_32(to, 5, from, (a3) - 8) else bn_32_set_0(to, 5)\
-	if (a2 != 0) bn_cp_32(to, 6, from, (a2) - 8) else bn_32_set_0(to, 6)\
-	if (a1 != 0) bn_cp_32(to, 7, from, (a1) - 8) else bn_32_set_0(to, 7)\
+	bn_cp_32(to, 0, from, (a8) - 8) \
+	bn_cp_32(to, 1, from, (a7) - 8) \
+	bn_cp_32(to, 2, from, (a6) - 8) \
+	bn_cp_32(to, 3, from, (a5) - 8) \
+	bn_cp_32(to, 4, from, (a4) - 8) \
+	bn_cp_32(to, 5, from, (a3) - 8) \
+	bn_cp_32(to, 6, from, (a2) - 8) \
+	bn_cp_32(to, 7, from, (a1) - 8) \
 	}
 
 int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
 	BN_CTX *ctx)
 	{
-#if BN_BITS2 == 32
 	int	i, top = a->top;
 	int	carry = 0;
 	register BN_ULONG *a_d = a->d, *r_d;
@@ -363,6 +550,17 @@
 		 c_d[BN_NIST_256_TOP],
 		*res;
 	size_t   mask;
+	union { bn_addsub_f f; size_t p; } u;
+	static const BIGNUM _bignum_nist_p_256_sqr = {
+		(BN_ULONG *)_nist_p_256_sqr,
+		sizeof(_nist_p_256_sqr)/sizeof(_nist_p_256_sqr[0]),
+		sizeof(_nist_p_256_sqr)/sizeof(_nist_p_256_sqr[0]),
+		0,BN_FLG_STATIC_DATA };
+
+	field = &_bignum_nist_p_256; /* just to make sure */
+
+ 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_256_sqr)>=0)
+		return BN_nnmod(r, a, field, ctx);
 
 	i = BN_ucmp(field, a);
 	if (i == 0)
@@ -373,9 +571,6 @@
 	else if (i > 0)
 		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
 
-	if (top == BN_NIST_256_TOP)
-		return BN_usub(r, a, field);
-
 	if (r != a)
 		{
 		if (!bn_wexpand(r, BN_NIST_256_TOP))
@@ -391,111 +586,84 @@
 	/*S1*/
 	nist_set_256(t_d, buf, 15, 14, 13, 12, 11, 0, 0, 0);
 	/*S2*/
-	nist_set_256(c_d,buf, 0, 15, 14, 13, 12, 0, 0, 0);
-	carry = bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP);
-	mask = 0-(size_t)bn_sub_words(c_d,t_d,_nist_p_256,BN_NIST_256_TOP);
-	mask = ~mask | (0-(size_t)carry);
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)t_d&~mask));
-
-	carry = bn_add_words(t_d, res, res, BN_NIST_256_TOP);
-	mask = 0-(size_t)bn_sub_words(c_d,t_d,_nist_p_256,BN_NIST_256_TOP);
-	mask = ~mask | (0-(size_t)carry);
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)t_d&~mask));
-
-	carry = bn_add_words(r_d, r_d, res, BN_NIST_256_TOP);
-	mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP);
-	mask = ~mask | (0-(size_t)carry);
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));
-
+	nist_set_256(c_d, buf, 0, 15, 14, 13, 12, 0, 0, 0);
+	carry = (int)bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP);
+	/* left shift */
+		{
+		register BN_ULONG *ap,t,c;
+		ap = t_d;
+		c=0;
+		for (i = BN_NIST_256_TOP; i != 0; --i)
+			{
+			t= *ap;
+			*(ap++)=((t<<1)|c)&BN_MASK2;
+			c=(t & BN_TBIT)?1:0;
+			}
+		carry <<= 1;
+		carry  |= c;
+		}
+	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
 	/*S3*/
 	nist_set_256(t_d, buf, 15, 14, 0, 0, 0, 10, 9, 8);
-	carry = bn_add_words(r_d, res, t_d, BN_NIST_256_TOP);
-	mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP);
-	mask = ~mask | (0-(size_t)carry);
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));
-
+	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
 	/*S4*/
 	nist_set_256(t_d, buf, 8, 13, 15, 14, 13, 11, 10, 9);
-	carry = bn_add_words(r_d, res, t_d, BN_NIST_256_TOP);
-	mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP);
-	mask = ~mask | (0-(size_t)carry);
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));
-
+	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
 	/*D1*/
 	nist_set_256(t_d, buf, 10, 8, 0, 0, 0, 13, 12, 11);
-#if BRANCH_FREE
-	carry = bn_sub_words(r_d, res, t_d, BN_NIST_256_TOP);
-	bn_add_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP);
-	mask = 0-(size_t)carry;
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));	
-#else
-	if (bn_sub_words(r_d, res, t_d, BN_NIST_256_TOP))
-		bn_add_words(r_d,r_d,_nist_p_256,BN_NIST_256_TOP);
-#endif
+	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
 	/*D2*/
 	nist_set_256(t_d, buf, 11, 9, 0, 0, 15, 14, 13, 12);
-#if BRANCH_FREE
-	carry = bn_sub_words(r_d, res, t_d, BN_NIST_256_TOP);
-	bn_add_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP);
-	mask = 0-(size_t)carry;
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));	
-#else
-	if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP))
-		bn_add_words(r_d,r_d,_nist_p_256,BN_NIST_256_TOP);
-#endif
+	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
 	/*D3*/
 	nist_set_256(t_d, buf, 12, 0, 10, 9, 8, 15, 14, 13);
-#if BRANCH_FREE
-	carry = bn_sub_words(r_d, res, t_d, BN_NIST_256_TOP);
-	bn_add_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP);
-	mask = 0-(size_t)carry;
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));	
-#else
-	if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP))
-		bn_add_words(r_d,r_d,_nist_p_256,BN_NIST_256_TOP);
-#endif
+	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
 	/*D4*/
 	nist_set_256(t_d, buf, 13, 0, 11, 10, 9, 0, 15, 14);
-#if BRANCH_FREE
-	carry = bn_sub_words(r_d, res, t_d, BN_NIST_256_TOP);
-	bn_add_words(c_d,r_d,_nist_p_256,BN_NIST_256_TOP);
-	mask = 0-(size_t)carry;
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));	
+	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
 
-	nist_cp_bn(r_d, res, BN_NIST_384_TOP);
-#else
-	if (bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP))
-		bn_add_words(r_d,r_d,_nist_p_256,BN_NIST_256_TOP);
-#endif
+	/* see BN_nist_mod_224 for explanation */
+	u.f = bn_sub_words;
+	if (carry > 0)
+		carry = (int)bn_sub_words(r_d,r_d,_nist_p_256[carry-1],BN_NIST_256_TOP);
+	else if (carry < 0)
+		{
+		carry = (int)bn_add_words(r_d,r_d,_nist_p_256[-carry-1],BN_NIST_256_TOP);
+		mask = 0-(size_t)carry;
+		u.p = ((size_t)bn_sub_words&mask) | ((size_t)bn_add_words&~mask);
+		}
+	else
+		carry = 1;
+
+	mask  = 0-(size_t)(*u.f)(c_d,r_d,_nist_p_256[0],BN_NIST_256_TOP);
+	mask &= 0-(size_t)carry;
+	res   = (BN_ULONG *)(((size_t)c_d&~mask) | ((size_t)r_d&mask));
+	nist_cp_bn(r_d, res, BN_NIST_256_TOP);
 	r->top = BN_NIST_256_TOP;
 	bn_correct_top(r);
 
 	return 1;
-#else	/* BN_BITS!=32 */
-	return 0;
-#endif
 	}
 
 #define nist_set_384(to,from,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \
 	{ \
-	if (a12 != 0) bn_cp_32(to, 0, from,  (a12) - 12) else bn_32_set_0(to, 0)\
-	if (a11 != 0) bn_cp_32(to, 1, from,  (a11) - 12) else bn_32_set_0(to, 1)\
-	if (a10 != 0) bn_cp_32(to, 2, from,  (a10) - 12) else bn_32_set_0(to, 2)\
-	if (a9 != 0)  bn_cp_32(to, 3, from,  (a9) - 12)  else bn_32_set_0(to, 3)\
-	if (a8 != 0)  bn_cp_32(to, 4, from,  (a8) - 12)  else bn_32_set_0(to, 4)\
-	if (a7 != 0)  bn_cp_32(to, 5, from,  (a7) - 12)  else bn_32_set_0(to, 5)\
-	if (a6 != 0)  bn_cp_32(to, 6, from,  (a6) - 12)  else bn_32_set_0(to, 6)\
-	if (a5 != 0)  bn_cp_32(to, 7, from,  (a5) - 12)  else bn_32_set_0(to, 7)\
-	if (a4 != 0)  bn_cp_32(to, 8, from,  (a4) - 12)  else bn_32_set_0(to, 8)\
-	if (a3 != 0)  bn_cp_32(to, 9, from,  (a3) - 12)  else bn_32_set_0(to, 9)\
-	if (a2 != 0)  bn_cp_32(to, 10, from, (a2) - 12)  else bn_32_set_0(to, 10)\
-	if (a1 != 0)  bn_cp_32(to, 11, from, (a1) - 12)  else bn_32_set_0(to, 11)\
+	bn_cp_32(to, 0, from,  (a12) - 12) \
+	bn_cp_32(to, 1, from,  (a11) - 12) \
+	bn_cp_32(to, 2, from,  (a10) - 12) \
+	bn_cp_32(to, 3, from,  (a9) - 12)  \
+	bn_cp_32(to, 4, from,  (a8) - 12)  \
+	bn_cp_32(to, 5, from,  (a7) - 12)  \
+	bn_cp_32(to, 6, from,  (a6) - 12)  \
+	bn_cp_32(to, 7, from,  (a5) - 12)  \
+	bn_cp_32(to, 8, from,  (a4) - 12)  \
+	bn_cp_32(to, 9, from,  (a3) - 12)  \
+	bn_cp_32(to, 10, from, (a2) - 12)  \
+	bn_cp_32(to, 11, from, (a1) - 12)  \
 	}
 
 int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
 	BN_CTX *ctx)
 	{
-#if BN_BITS2 == 32
 	int	i, top = a->top;
 	int	carry = 0;
 	register BN_ULONG *r_d, *a_d = a->d;
@@ -504,6 +672,18 @@
 		 c_d[BN_NIST_384_TOP],
 		*res;
 	size_t	 mask;
+	union { bn_addsub_f f; size_t p; } u;
+	static const BIGNUM _bignum_nist_p_384_sqr = {
+		(BN_ULONG *)_nist_p_384_sqr,
+		sizeof(_nist_p_384_sqr)/sizeof(_nist_p_384_sqr[0]),
+		sizeof(_nist_p_384_sqr)/sizeof(_nist_p_384_sqr[0]),
+		0,BN_FLG_STATIC_DATA };
+
+
+	field = &_bignum_nist_p_384; /* just to make sure */
+
+ 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_384_sqr)>=0)
+		return BN_nnmod(r, a, field, ctx);
 
 	i = BN_ucmp(field, a);
 	if (i == 0)
@@ -514,9 +694,6 @@
 	else if (i > 0)
 		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
 
-	if (top == BN_NIST_384_TOP)
-		return BN_usub(r, a, field);
-
 	if (r != a)
 		{
 		if (!bn_wexpand(r, BN_NIST_384_TOP))
@@ -544,149 +721,116 @@
 			}
 		*ap=c;
 		}
-	carry = bn_add_words(r_d+(128/BN_BITS2), r_d+(128/BN_BITS2), 
+	carry = (int)bn_add_words(r_d+(128/BN_BITS2), r_d+(128/BN_BITS2), 
 		t_d, BN_NIST_256_TOP);
-	/*
-	 * we need if (result>=modulus) subtract(result,modulus);
-	 * in n-bit space this can be expressed as
-	 * if (carry || result>=modulus) subtract(result,modulus);
-	 * the catch is that comparison implies subtraction and
-	 * therefore one can write tmp=subtract(result,modulus);
-	 * and then if(carry || !borrow) result=tmp; this's what
-	 * happens below, but without explicit if:-) a.
-	 */
-	mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP);
-	mask = ~mask | (0-(size_t)carry);
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));
-
 	/*S2 */
-	carry = bn_add_words(r_d, res, buf, BN_NIST_384_TOP);
-	mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP);
-	mask = ~mask | (0-(size_t)carry);
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));
-
+	carry += (int)bn_add_words(r_d, r_d, buf, BN_NIST_384_TOP);
 	/*S3*/
 	nist_set_384(t_d,buf,20,19,18,17,16,15,14,13,12,23,22,21);
-	carry = bn_add_words(r_d, res, t_d, BN_NIST_384_TOP);
-	mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP);
-	mask = ~mask | (0-(size_t)carry);
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));
-
+	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
 	/*S4*/
 	nist_set_384(t_d,buf,19,18,17,16,15,14,13,12,20,0,23,0);
-	carry = bn_add_words(r_d, res, t_d, BN_NIST_384_TOP);
-	mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP);
-	mask = ~mask | (0-(size_t)carry);
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));
-
+	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
 	/*S5*/
 	nist_set_384(t_d, buf,0,0,0,0,23,22,21,20,0,0,0,0);
-	carry = bn_add_words(r_d, res, t_d, BN_NIST_384_TOP);
-	mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP);
-	mask = ~mask | (0-(size_t)carry);
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));
-
+	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
 	/*S6*/
 	nist_set_384(t_d,buf,0,0,0,0,0,0,23,22,21,0,0,20);
-	carry = bn_add_words(r_d, res, t_d, BN_NIST_384_TOP);
-	mask = 0-(size_t)bn_sub_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP);
-	mask = ~mask | (0-(size_t)carry);
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));
-
+	carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
 	/*D1*/
 	nist_set_384(t_d,buf,22,21,20,19,18,17,16,15,14,13,12,23);
-#if BRANCH_FREE
-	carry = bn_sub_words(r_d, res, t_d, BN_NIST_384_TOP);
-	bn_add_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP);
-	mask = 0-(size_t)carry;
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));
-#else
-	if (bn_sub_words(r_d, res, t_d, BN_NIST_384_TOP))
-		bn_add_words(r_d,r_d,_nist_p_384,BN_NIST_384_TOP);
-#endif
+	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
 	/*D2*/
 	nist_set_384(t_d,buf,0,0,0,0,0,0,0,23,22,21,20,0);
-#if BRANCH_FREE
-	carry = bn_sub_words(r_d, res, t_d, BN_NIST_384_TOP);
-	bn_add_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP);
-	mask = 0-(size_t)carry;
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));
-#else
-	if (bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP))
-		bn_add_words(r_d,r_d,_nist_p_384,BN_NIST_384_TOP);
-#endif
+	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
 	/*D3*/
 	nist_set_384(t_d,buf,0,0,0,0,0,0,0,23,23,0,0,0);
-#if BRANCH_FREE
-	carry = bn_sub_words(r_d, res, t_d, BN_NIST_384_TOP);
-	bn_add_words(c_d,r_d,_nist_p_384,BN_NIST_384_TOP);
-	mask = 0-(size_t)carry;
-	res = (BN_ULONG *)(((size_t)c_d&mask) | ((size_t)r_d&~mask));
+	carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
 
+	/* see BN_nist_mod_224 for explanation */
+	u.f = bn_sub_words;
+	if (carry > 0)
+		carry = (int)bn_sub_words(r_d,r_d,_nist_p_384[carry-1],BN_NIST_384_TOP);
+	else if (carry < 0)
+		{
+		carry = (int)bn_add_words(r_d,r_d,_nist_p_384[-carry-1],BN_NIST_384_TOP);
+		mask = 0-(size_t)carry;
+		u.p = ((size_t)bn_sub_words&mask) | ((size_t)bn_add_words&~mask);
+		}
+	else
+		carry = 1;
+
+	mask  = 0-(size_t)(*u.f)(c_d,r_d,_nist_p_384[0],BN_NIST_384_TOP);
+	mask &= 0-(size_t)carry;
+	res   = (BN_ULONG *)(((size_t)c_d&~mask) | ((size_t)r_d&mask));
 	nist_cp_bn(r_d, res, BN_NIST_384_TOP);
-#else
-	if (bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP))
-		bn_add_words(r_d,r_d,_nist_p_384,BN_NIST_384_TOP);
-#endif
 	r->top = BN_NIST_384_TOP;
 	bn_correct_top(r);
 
 	return 1;
-#else	/* BN_BITS!=32 */
-	return 0;
-#endif
 	}
 
+#define BN_NIST_521_RSHIFT	(521%BN_BITS2)
+#define BN_NIST_521_LSHIFT	(BN_BITS2-BN_NIST_521_RSHIFT)
+#define BN_NIST_521_TOP_MASK	((BN_ULONG)BN_MASK2>>BN_NIST_521_LSHIFT)
+
 int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
 	BN_CTX *ctx)
 	{
-#if BN_BITS2 == 64
-#define BN_NIST_521_TOP_MASK	(BN_ULONG)0x1FF
-#elif BN_BITS2 == 32
-#define BN_NIST_521_TOP_MASK	(BN_ULONG)0x1FF
-#endif
-	int	top, ret = 0;
-	BN_ULONG *r_d;
-	BIGNUM	*tmp;
+	int	top = a->top, i;
+	BN_ULONG *r_d, *a_d = a->d,
+		 t_d[BN_NIST_521_TOP],
+		 val,tmp,*res;
+	size_t	mask;
+	static const BIGNUM _bignum_nist_p_521_sqr = {
+		(BN_ULONG *)_nist_p_521_sqr,
+		sizeof(_nist_p_521_sqr)/sizeof(_nist_p_521_sqr[0]),
+		sizeof(_nist_p_521_sqr)/sizeof(_nist_p_521_sqr[0]),
+		0,BN_FLG_STATIC_DATA };
 
-	/* check whether a reduction is necessary */
-	top = a->top;
-	if (top < BN_NIST_521_TOP  || ( top == BN_NIST_521_TOP &&
-           (!(a->d[BN_NIST_521_TOP-1] & ~(BN_NIST_521_TOP_MASK)))))
+	field = &_bignum_nist_p_521; /* just to make sure */
+
+ 	if (BN_is_negative(a) || BN_ucmp(a,&_bignum_nist_p_521_sqr)>=0)
+		return BN_nnmod(r, a, field, ctx);
+
+	i = BN_ucmp(field, a);
+	if (i == 0)
+		{
+		BN_zero(r);
+		return 1;
+		}
+	else if (i > 0)
 		return (r == a)? 1 : (BN_copy(r ,a) != NULL);
 
-	BN_CTX_start(ctx);
-	tmp = BN_CTX_get(ctx);
-	if (!tmp)
-		goto err;
-
-	if (!bn_wexpand(tmp, BN_NIST_521_TOP))
-		goto err;
-	nist_cp_bn(tmp->d, a->d, BN_NIST_521_TOP);
-
-	tmp->top = BN_NIST_521_TOP;
-        tmp->d[BN_NIST_521_TOP-1]  &= BN_NIST_521_TOP_MASK;
-	bn_correct_top(tmp);
-
-	if (!BN_rshift(r, a, 521))
-		goto err;
-
-	if (!BN_uadd(r, tmp, r))
-		goto err;
-	top = r->top;
-	r_d = r->d;
-	if (top == BN_NIST_521_TOP  && 
-           (r_d[BN_NIST_521_TOP-1] & ~(BN_NIST_521_TOP_MASK)))
+	if (r != a)
 		{
-		BN_NIST_ADD_ONE(r_d)
-		r->d[BN_NIST_521_TOP-1] &= BN_NIST_521_TOP_MASK; 
+		if (!bn_wexpand(r,BN_NIST_521_TOP))
+			return 0;
+		r_d = r->d;
+		nist_cp_bn(r_d,a_d, BN_NIST_521_TOP);
 		}
+	else
+		r_d = a_d;
+
+	/* upper 521 bits, copy ... */
+	nist_cp_bn_0(t_d,a_d + (BN_NIST_521_TOP-1), top - (BN_NIST_521_TOP-1),BN_NIST_521_TOP);
+	/* ... and right shift */
+	for (val=t_d[0],i=0; i<BN_NIST_521_TOP-1; i++)
+		{
+		tmp = val>>BN_NIST_521_RSHIFT;
+		val = t_d[i+1];
+		t_d[i] = (tmp | val<<BN_NIST_521_LSHIFT) & BN_MASK2;
+		}
+	t_d[i] = val>>BN_NIST_521_RSHIFT;
+	/* lower 521 bits */
+	r_d[i] &= BN_NIST_521_TOP_MASK;
+
+	bn_add_words(r_d,r_d,t_d,BN_NIST_521_TOP);
+	mask = 0-(size_t)bn_sub_words(t_d,r_d,_nist_p_521,BN_NIST_521_TOP);
+	res  = (BN_ULONG *)(((size_t)t_d&~mask) | ((size_t)r_d&mask));
+	nist_cp_bn(r_d,res,BN_NIST_521_TOP);
+	r->top = BN_NIST_521_TOP;
 	bn_correct_top(r);
 
-	ret = 1;
-err:
-	BN_CTX_end(ctx);
-
-	bn_check_top(r);
-	return ret;
+	return 1;
 	}
diff --git a/crypto/bn/bn_opt.c b/crypto/bn/bn_opt.c
new file mode 100644
index 0000000..21cbb38
--- /dev/null
+++ b/crypto/bn/bn_opt.c
@@ -0,0 +1,87 @@
+/* crypto/bn/bn_opt.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef BN_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
+#endif
+
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+char *BN_options(void)
+	{
+	static int init=0;
+	static char data[16];
+
+	if (!init)
+		{
+		init++;
+#ifdef BN_LLONG
+		BIO_snprintf(data,sizeof data,"bn(%d,%d)",
+			     (int)sizeof(BN_ULLONG)*8,(int)sizeof(BN_ULONG)*8);
+#else
+		BIO_snprintf(data,sizeof data,"bn(%d,%d)",
+			     (int)sizeof(BN_ULONG)*8,(int)sizeof(BN_ULONG)*8);
+#endif
+		}
+	return(data);
+	}
diff --git a/crypto/bn/bn_rand.c b/crypto/bn/bn_rand.c
index f51830b..b376c28 100644
--- a/crypto/bn/bn_rand.c
+++ b/crypto/bn/bn_rand.c
@@ -227,7 +227,7 @@
 
 
 /* random number r:  0 <= r < range */
-static int bn_rand_range(int pseudo, BIGNUM *r, BIGNUM *range)
+static int bn_rand_range(int pseudo, BIGNUM *r, const BIGNUM *range)
 	{
 	int (*bn_rand)(BIGNUM *, int, int, int) = pseudo ? BN_pseudo_rand : BN_rand;
 	int n;
@@ -294,12 +294,12 @@
 	}
 
 
-int	BN_rand_range(BIGNUM *r, BIGNUM *range)
+int	BN_rand_range(BIGNUM *r, const BIGNUM *range)
 	{
 	return bn_rand_range(0, r, range);
 	}
 
-int	BN_pseudo_rand_range(BIGNUM *r, BIGNUM *range)
+int	BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range)
 	{
 	return bn_rand_range(1, r, range);
 	}
diff --git a/crypto/bn/bn_shift.c b/crypto/bn/bn_shift.c
index de9312d..c4d301a 100644
--- a/crypto/bn/bn_shift.c
+++ b/crypto/bn/bn_shift.c
@@ -177,7 +177,7 @@
 	nw=n/BN_BITS2;
 	rb=n%BN_BITS2;
 	lb=BN_BITS2-rb;
-	if (nw > a->top || a->top == 0)
+	if (nw >= a->top || a->top == 0)
 		{
 		BN_zero(r);
 		return(1);
diff --git a/crypto/bn/bn_x931p.c b/crypto/bn/bn_x931p.c
new file mode 100644
index 0000000..04c5c87
--- /dev/null
+++ b/crypto/bn/bn_x931p.c
@@ -0,0 +1,272 @@
+/* bn_x931p.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project 2005.
+ */
+/* ====================================================================
+ * Copyright (c) 2005 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <openssl/bn.h>
+
+/* X9.31 routines for prime derivation */
+
+/* X9.31 prime derivation. This is used to generate the primes pi
+ * (p1, p2, q1, q2) from a parameter Xpi by checking successive odd
+ * integers.
+ */
+
+static int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx,
+			BN_GENCB *cb)
+	{
+	int i = 0;
+	if (!BN_copy(pi, Xpi))
+		return 0;
+	if (!BN_is_odd(pi) && !BN_add_word(pi, 1))
+		return 0;
+	for(;;)
+		{
+		i++;
+		BN_GENCB_call(cb, 0, i);
+		/* NB 27 MR is specificed in X9.31 */
+		if (BN_is_prime_fasttest_ex(pi, 27, ctx, 1, cb))
+			break;
+		if (!BN_add_word(pi, 2))
+			return 0;
+		}
+	BN_GENCB_call(cb, 2, i);
+	return 1;
+	}
+
+/* This is the main X9.31 prime derivation function. From parameters
+ * Xp1, Xp2 and Xp derive the prime p. If the parameters p1 or p2 are
+ * not NULL they will be returned too: this is needed for testing.
+ */
+
+int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+			const BIGNUM *Xp, const BIGNUM *Xp1, const BIGNUM *Xp2,
+			const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb)
+	{
+	int ret = 0;
+
+	BIGNUM *t, *p1p2, *pm1;
+
+	/* Only even e supported */
+	if (!BN_is_odd(e))
+		return 0;
+
+	BN_CTX_start(ctx);
+	if (!p1)
+		p1 = BN_CTX_get(ctx);
+
+	if (!p2)
+		p2 = BN_CTX_get(ctx);
+
+	t = BN_CTX_get(ctx);
+
+	p1p2 = BN_CTX_get(ctx);
+
+	pm1 = BN_CTX_get(ctx);
+
+	if (!bn_x931_derive_pi(p1, Xp1, ctx, cb))
+		goto err;
+
+	if (!bn_x931_derive_pi(p2, Xp2, ctx, cb))
+		goto err;
+
+	if (!BN_mul(p1p2, p1, p2, ctx))
+		goto err;
+
+	/* First set p to value of Rp */
+
+	if (!BN_mod_inverse(p, p2, p1, ctx))
+		goto err;
+
+	if (!BN_mul(p, p, p2, ctx))
+		goto err;
+
+	if (!BN_mod_inverse(t, p1, p2, ctx))
+		goto err;
+
+	if (!BN_mul(t, t, p1, ctx))
+		goto err;
+
+	if (!BN_sub(p, p, t))
+		goto err;
+
+	if (p->neg && !BN_add(p, p, p1p2))
+		goto err;
+
+	/* p now equals Rp */
+
+	if (!BN_mod_sub(p, p, Xp, p1p2, ctx))
+		goto err;
+
+	if (!BN_add(p, p, Xp))
+		goto err;
+
+	/* p now equals Yp0 */
+
+	for (;;)
+		{
+		int i = 1;
+		BN_GENCB_call(cb, 0, i++);
+		if (!BN_copy(pm1, p))
+			goto err;
+		if (!BN_sub_word(pm1, 1))
+			goto err;
+		if (!BN_gcd(t, pm1, e, ctx))
+			goto err;
+		if (BN_is_one(t)
+		/* X9.31 specifies 8 MR and 1 Lucas test or any prime test
+		 * offering similar or better guarantees 50 MR is considerably 
+		 * better.
+		 */
+			&& BN_is_prime_fasttest_ex(p, 50, ctx, 1, cb))
+			break;
+		if (!BN_add(p, p, p1p2))
+			goto err;
+		}
+
+	BN_GENCB_call(cb, 3, 0);
+
+	ret = 1;
+
+	err:
+
+	BN_CTX_end(ctx);
+
+	return ret;
+	}
+
+/* Generate pair of paramters Xp, Xq for X9.31 prime generation.
+ * Note: nbits paramter is sum of number of bits in both.
+ */
+
+int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx)
+	{
+	BIGNUM *t;
+	int i;
+	/* Number of bits for each prime is of the form
+	 * 512+128s for s = 0, 1, ...
+	 */
+	if ((nbits < 1024) || (nbits & 0xff))
+		return 0;
+	nbits >>= 1;
+	/* The random value Xp must be between sqrt(2) * 2^(nbits-1) and
+	 * 2^nbits - 1. By setting the top two bits we ensure that the lower
+	 * bound is exceeded.
+	 */
+	if (!BN_rand(Xp, nbits, 1, 0))
+		return 0;
+
+	BN_CTX_start(ctx);
+	t = BN_CTX_get(ctx);
+
+	for (i = 0; i < 1000; i++)
+		{
+		if (!BN_rand(Xq, nbits, 1, 0))
+			return 0;
+		/* Check that |Xp - Xq| > 2^(nbits - 100) */
+		BN_sub(t, Xp, Xq);
+		if (BN_num_bits(t) > (nbits - 100))
+			break;
+		}
+
+	BN_CTX_end(ctx);
+
+	if (i < 1000)
+		return 1;
+
+	return 0;
+
+	}
+
+/* Generate primes using X9.31 algorithm. Of the values p, p1, p2, Xp1
+ * and Xp2 only 'p' needs to be non-NULL. If any of the others are not NULL
+ * the relevant parameter will be stored in it.
+ *
+ * Due to the fact that |Xp - Xq| > 2^(nbits - 100) must be satisfied Xp and Xq
+ * are generated using the previous function and supplied as input.
+ */
+
+int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2,
+			BIGNUM *Xp1, BIGNUM *Xp2,
+			const BIGNUM *Xp,
+			const BIGNUM *e, BN_CTX *ctx,
+			BN_GENCB *cb)
+	{
+	int ret = 0;
+
+	BN_CTX_start(ctx);
+	if (!Xp1)
+		Xp1 = BN_CTX_get(ctx);
+	if (!Xp2)
+		Xp2 = BN_CTX_get(ctx);
+
+	if (!BN_rand(Xp1, 101, 0, 0))
+		goto error;
+	if (!BN_rand(Xp2, 101, 0, 0))
+		goto error;
+	if (!BN_X931_derive_prime_ex(p, p1, p2, Xp, Xp1, Xp2, e, ctx, cb))
+		goto error;
+
+	ret = 1;
+
+	error:
+	BN_CTX_end(ctx);
+
+	return ret;
+
+	}
+
diff --git a/crypto/bn/bntest.c b/crypto/bn/bntest.c
index 310763e..cf19038 100644
--- a/crypto/bn/bntest.c
+++ b/crypto/bn/bntest.c
@@ -926,7 +926,7 @@
 		BN_bntest_rand(b,2+i,0,0); /**/
 
 		if (!BN_mod_exp(d,a,b,c,ctx))
-			return(00);
+			return(0);
 
 		if (bp != NULL)
 			{
@@ -1028,7 +1028,7 @@
 		BN_bntest_rand(b,2+i,0,0); /**/
 
 		if (!BN_exp(d,a,b,ctx))
-			return(00);
+			return(0);
 
 		if (bp != NULL)
 			{
diff --git a/crypto/buffer/Makefile b/crypto/buffer/Makefile
index 9f3a88d..9e0f46e 100644
--- a/crypto/buffer/Makefile
+++ b/crypto/buffer/Makefile
@@ -17,8 +17,8 @@
 APPS=
 
 LIB=$(TOP)/libcrypto.a
-LIBSRC= buffer.c buf_err.c
-LIBOBJ= buffer.o buf_err.o
+LIBSRC= buffer.c buf_str.c buf_err.c
+LIBOBJ= buffer.o buf_str.o buf_err.o
 
 SRC= $(LIBSRC)
 
@@ -33,7 +33,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -81,6 +81,13 @@
 buf_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
 buf_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 buf_err.o: buf_err.c
+buf_str.o: ../../e_os.h ../../include/openssl/bio.h
+buf_str.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+buf_str.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+buf_str.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+buf_str.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+buf_str.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+buf_str.o: ../../include/openssl/symhacks.h ../cryptlib.h buf_str.c
 buffer.o: ../../e_os.h ../../include/openssl/bio.h
 buffer.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 buffer.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
diff --git a/crypto/buffer/buf_str.c b/crypto/buffer/buf_str.c
new file mode 100644
index 0000000..28dd1e4
--- /dev/null
+++ b/crypto/buffer/buf_str.c
@@ -0,0 +1,116 @@
+/* crypto/buffer/buf_str.c */
+/* ====================================================================
+ * Copyright (c) 2007 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/buffer.h>
+
+char *BUF_strdup(const char *str)
+	{
+	if (str == NULL) return(NULL);
+	return BUF_strndup(str, strlen(str));
+	}
+
+char *BUF_strndup(const char *str, size_t siz)
+	{
+	char *ret;
+
+	if (str == NULL) return(NULL);
+
+	ret=OPENSSL_malloc(siz+1);
+	if (ret == NULL) 
+		{
+		BUFerr(BUF_F_BUF_STRNDUP,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	BUF_strlcpy(ret,str,siz+1);
+	return(ret);
+	}
+
+void *BUF_memdup(const void *data, size_t siz)
+	{
+	void *ret;
+
+	if (data == NULL) return(NULL);
+
+	ret=OPENSSL_malloc(siz);
+	if (ret == NULL) 
+		{
+		BUFerr(BUF_F_BUF_MEMDUP,ERR_R_MALLOC_FAILURE);
+		return(NULL);
+		}
+	return memcpy(ret, data, siz);
+	}	
+
+size_t BUF_strlcpy(char *dst, const char *src, size_t size)
+	{
+	size_t l = 0;
+	for(; size > 1 && *src; size--)
+		{
+		*dst++ = *src++;
+		l++;
+		}
+	if (size)
+		*dst = '\0';
+	return l + strlen(src);
+	}
+
+size_t BUF_strlcat(char *dst, const char *src, size_t size)
+	{
+	size_t l = 0;
+	for(; size > 0 && *dst; size--, dst++)
+		l++;
+	return l + BUF_strlcpy(dst, src, size);
+	}
diff --git a/crypto/buffer/buffer.c b/crypto/buffer/buffer.c
index 3bf03c7..b3e9477 100644
--- a/crypto/buffer/buffer.c
+++ b/crypto/buffer/buffer.c
@@ -161,61 +161,3 @@
 		}
 	return(len);
 	}
-
-char *BUF_strdup(const char *str)
-	{
-	if (str == NULL) return(NULL);
-	return BUF_strndup(str, strlen(str));
-	}
-
-char *BUF_strndup(const char *str, size_t siz)
-	{
-	char *ret;
-
-	if (str == NULL) return(NULL);
-
-	ret=OPENSSL_malloc(siz+1);
-	if (ret == NULL) 
-		{
-		BUFerr(BUF_F_BUF_STRNDUP,ERR_R_MALLOC_FAILURE);
-		return(NULL);
-		}
-	BUF_strlcpy(ret,str,siz+1);
-	return(ret);
-	}
-
-void *BUF_memdup(const void *data, size_t siz)
-	{
-	void *ret;
-
-	if (data == NULL) return(NULL);
-
-	ret=OPENSSL_malloc(siz);
-	if (ret == NULL) 
-		{
-		BUFerr(BUF_F_BUF_MEMDUP,ERR_R_MALLOC_FAILURE);
-		return(NULL);
-		}
-	return memcpy(ret, data, siz);
-	}	
-
-size_t BUF_strlcpy(char *dst, const char *src, size_t size)
-	{
-	size_t l = 0;
-	for(; size > 1 && *src; size--)
-		{
-		*dst++ = *src++;
-		l++;
-		}
-	if (size)
-		*dst = '\0';
-	return l + strlen(src);
-	}
-
-size_t BUF_strlcat(char *dst, const char *src, size_t size)
-	{
-	size_t l = 0;
-	for(; size > 0 && *dst; size--, dst++)
-		l++;
-	return l + BUF_strlcpy(dst, src, size);
-	}
diff --git a/crypto/camellia/Makefile b/crypto/camellia/Makefile
index 1579de5..dfb1295 100644
--- a/crypto/camellia/Makefile
+++ b/crypto/camellia/Makefile
@@ -41,7 +41,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
diff --git a/crypto/camellia/asm/cmll-x86.pl b/crypto/camellia/asm/cmll-x86.pl
new file mode 100644
index 0000000..0812815
--- /dev/null
+++ b/crypto/camellia/asm/cmll-x86.pl
@@ -0,0 +1,1138 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Copyright (c) 2008 Andy Polyakov <appro@openssl.org>
+#
+# This module may be used under the terms of either the GNU General
+# Public License version 2 or later, the GNU Lesser General Public
+# License version 2.1 or later, the Mozilla Public License version
+# 1.1 or the BSD License. The exact terms of either license are
+# distributed along with this module. For further details see
+# http://www.openssl.org/~appro/camellia/.
+# ====================================================================
+
+# Performance in cycles per processed byte (less is better) in
+# 'openssl speed ...' benchmark:
+#
+#			AMD K8	Core2	PIII	P4
+# -evp camellia-128-ecb	21.5	22.8	27.0	28.9
+# + over gcc 3.4.6	+90/11% +70/10%	+53/4%	+160/64%
+# + over icc 8.0	+48/19% +21/15%	+21/17%	+55/37%
+#
+# camellia-128-cbc	17.3	21.1	23.9	25.9
+#
+# 128-bit key setup	196	280	256	240	cycles/key
+# + over gcc 3.4.6	+30/0%	+17/11%	+11/0%	+63/40%
+# + over icc 8.0	+18/3%	+10/0%	+10/3%	+21/10%
+#
+# Pairs of numbers in "+" rows represent performance improvement over
+# compiler generated position-independent code, PIC, and non-PIC
+# respectively. PIC results are of greater relevance, as this module
+# is position-independent, i.e. suitable for a shared library or PIE.
+# Position independence "costs" one register, which is why compilers
+# are so close with non-PIC results, they have an extra register to
+# spare. CBC results are better than ECB ones thanks to "zero-copy"
+# private _x86_* interface, and are ~30-40% better than with compiler
+# generated cmll_cbc.o, and reach ~80-90% of x86_64 performance on
+# same CPU (where applicable).
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86asm.pl";
+
+$OPENSSL=1;
+
+&asm_init($ARGV[0],"cmll-586.pl",$ARGV[$#ARGV] eq "386");
+
+@T=("eax","ebx","ecx","edx");
+$idx="esi";
+$key="edi";
+$Tbl="ebp";
+
+# stack frame layout in _x86_Camellia_* routines, frame is allocated
+# by caller
+$__ra=&DWP(0,"esp");	# return address
+$__s0=&DWP(4,"esp");	# s0 backing store
+$__s1=&DWP(8,"esp");	# s1 backing store
+$__s2=&DWP(12,"esp");	# s2 backing store
+$__s3=&DWP(16,"esp");	# s3 backing store
+$__end=&DWP(20,"esp");	# pointer to end/start of key schedule
+
+# stack frame layout in Camellia_[en|crypt] routines, which differs from
+# above by 4 and overlaps by pointer to end/start of key schedule
+$_end=&DWP(16,"esp");
+$_esp=&DWP(20,"esp");
+
+# const unsigned int Camellia_SBOX[4][256];
+# Well, sort of... Camellia_SBOX[0][] is interleaved with [1][],
+# and [2][] - with [3][]. This is done to optimize code size.
+$SBOX1_1110=0;		# Camellia_SBOX[0]
+$SBOX4_4404=4;		# Camellia_SBOX[1]
+$SBOX2_0222=2048;	# Camellia_SBOX[2]
+$SBOX3_3033=2052;	# Camellia_SBOX[3]
+&static_label("Camellia_SIGMA");
+&static_label("Camellia_SBOX");
+
+sub Camellia_Feistel {
+my $i=@_[0];
+my $seed=defined(@_[1])?@_[1]:0;
+my $scale=$seed<0?-8:8;
+my $frame=defined(@_[2])?@_[2]:0;
+my $j=($i&1)*2;
+my $t0=@T[($j)%4],$t1=@T[($j+1)%4],$t2=@T[($j+2)%4],$t3=@T[($j+3)%4];
+
+	&xor	($t0,$idx);				# t0^=key[0]
+	&xor	($t1,&DWP($seed+$i*$scale+4,$key));	# t1^=key[1]
+	&movz	($idx,&HB($t0));			# (t0>>8)&0xff
+	&mov	($t3,&DWP($SBOX3_3033,$Tbl,$idx,8));	# t3=SBOX3_3033[0]
+	&movz	($idx,&LB($t0));			# (t0>>0)&0xff
+	&xor	($t3,&DWP($SBOX4_4404,$Tbl,$idx,8));	# t3^=SBOX4_4404[0]
+	&shr	($t0,16);
+	&movz	($idx,&LB($t1));			# (t1>>0)&0xff
+	&mov	($t2,&DWP($SBOX1_1110,$Tbl,$idx,8));	# t2=SBOX1_1110[1]
+	&movz	($idx,&HB($t0));			# (t0>>24)&0xff
+	&xor	($t3,&DWP($SBOX1_1110,$Tbl,$idx,8));	# t3^=SBOX1_1110[0]
+	&movz	($idx,&HB($t1));			# (t1>>8)&0xff
+	&xor	($t2,&DWP($SBOX4_4404,$Tbl,$idx,8));	# t2^=SBOX4_4404[1]
+	&shr	($t1,16);
+	&movz	($t0,&LB($t0));				# (t0>>16)&0xff
+	&xor	($t3,&DWP($SBOX2_0222,$Tbl,$t0,8));	# t3^=SBOX2_0222[0]
+	&movz	($idx,&HB($t1));			# (t1>>24)&0xff
+	&mov	($t0,&DWP($frame+4*(($j+3)%4),"esp"));	# prefetch "s3"
+	&xor	($t2,$t3);				# t2^=t3
+	&rotr	($t3,8);				# t3=RightRotate(t3,8)
+	&xor	($t2,&DWP($SBOX2_0222,$Tbl,$idx,8));	# t2^=SBOX2_0222[1]
+	&movz	($idx,&LB($t1));			# (t1>>16)&0xff
+	&mov	($t1,&DWP($frame+4*(($j+2)%4),"esp"));	# prefetch "s2"
+	&xor	($t3,$t0);				# t3^=s3
+	&xor	($t2,&DWP($SBOX3_3033,$Tbl,$idx,8));	# t2^=SBOX3_3033[1]
+	&mov	($idx,&DWP($seed+($i+1)*$scale,$key));	# prefetch key[i+1]
+	&xor	($t3,$t2);				# t3^=t2
+	&mov	(&DWP($frame+4*(($j+3)%4),"esp"),$t3);	# s3=t3
+	&xor	($t2,$t1);				# t2^=s2
+	&mov	(&DWP($frame+4*(($j+2)%4),"esp"),$t2);	# s2=t2
+}
+
+# void Camellia_EncryptBlock_Rounds(
+#		int grandRounds,
+#		const Byte plaintext[],
+#		const KEY_TABLE_TYPE keyTable,
+#		Byte ciphertext[])
+&function_begin("Camellia_EncryptBlock_Rounds");
+	&mov	("eax",&wparam(0));	# load grandRounds
+	&mov	($idx,&wparam(1));	# load plaintext pointer
+	&mov	($key,&wparam(2));	# load key schedule pointer
+
+	&mov	("ebx","esp");
+	&sub	("esp",7*4);		# place for s[0-3],keyEnd,esp and ra
+	&and	("esp",-64);
+
+	# place stack frame just "above mod 1024" the key schedule
+	# this ensures that cache associativity of 2 suffices
+	&lea	("ecx",&DWP(-64-63,$key));
+	&sub	("ecx","esp");
+	&neg	("ecx");
+	&and	("ecx",0x3C0);	# modulo 1024, but aligned to cache-line
+	&sub	("esp","ecx");
+	&add	("esp",4);	# 4 is reserved for callee's return address
+
+	&shl	("eax",6);
+	&lea	("eax",&DWP(0,$key,"eax"));
+	&mov	($_esp,"ebx");	# save %esp
+	&mov	($_end,"eax");	# save keyEnd
+
+	&call	(&label("pic_point"));
+	&set_label("pic_point");
+	&blindpop($Tbl);
+	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
+
+	&mov	(@T[0],&DWP(0,$idx));	# load plaintext
+	&mov	(@T[1],&DWP(4,$idx));
+	&mov	(@T[2],&DWP(8,$idx));
+	&bswap	(@T[0]);
+	&mov	(@T[3],&DWP(12,$idx));
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+
+	&call	("_x86_Camellia_encrypt");
+
+	&mov	("esp",$_esp);
+	&bswap	(@T[0]);
+	&mov	($idx,&wparam(3));	# load ciphertext pointer
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+	&mov	(&DWP(0,$idx),@T[0]);	# write ciphertext
+	&mov	(&DWP(4,$idx),@T[1]);
+	&mov	(&DWP(8,$idx),@T[2]);
+	&mov	(&DWP(12,$idx),@T[3]);
+&function_end("Camellia_EncryptBlock_Rounds");
+# V1.x API
+&function_begin_B("Camellia_EncryptBlock");
+	&mov	("eax",128);
+	&sub	("eax",&wparam(0));	# load keyBitLength
+	&mov	("eax",3);
+	&adc	("eax",0);		# keyBitLength==128?3:4
+	&mov	(&wparam(0),"eax");
+	&jmp	(&label("Camellia_EncryptBlock_Rounds"));
+&function_end_B("Camellia_EncryptBlock");
+
+if ($OPENSSL) {
+# void Camellia_encrypt(
+#		const unsigned char *in,
+#		unsigned char *out,
+#		const CAMELLIA_KEY *key)
+&function_begin("Camellia_encrypt");
+	&mov	($idx,&wparam(0));	# load plaintext pointer
+	&mov	($key,&wparam(2));	# load key schedule pointer
+
+	&mov	("ebx","esp");
+	&sub	("esp",7*4);		# place for s[0-3],keyEnd,esp and ra
+	&and	("esp",-64);
+	&mov	("eax",&DWP(272,$key));	# load grandRounds counter
+
+	# place stack frame just "above mod 1024" the key schedule
+	# this ensures that cache associativity of 2 suffices
+	&lea	("ecx",&DWP(-64-63,$key));
+	&sub	("ecx","esp");
+	&neg	("ecx");
+	&and	("ecx",0x3C0);	# modulo 1024, but aligned to cache-line
+	&sub	("esp","ecx");
+	&add	("esp",4);	# 4 is reserved for callee's return address
+
+	&shl	("eax",6);
+	&lea	("eax",&DWP(0,$key,"eax"));
+	&mov	($_esp,"ebx");	# save %esp
+	&mov	($_end,"eax");	# save keyEnd
+
+	&call	(&label("pic_point"));
+	&set_label("pic_point");
+	&blindpop($Tbl);
+	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
+
+	&mov	(@T[0],&DWP(0,$idx));	# load plaintext
+	&mov	(@T[1],&DWP(4,$idx));
+	&mov	(@T[2],&DWP(8,$idx));
+	&bswap	(@T[0]);
+	&mov	(@T[3],&DWP(12,$idx));
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+
+	&call	("_x86_Camellia_encrypt");
+
+	&mov	("esp",$_esp);
+	&bswap	(@T[0]);
+	&mov	($idx,&wparam(1));	# load ciphertext pointer
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+	&mov	(&DWP(0,$idx),@T[0]);	# write ciphertext
+	&mov	(&DWP(4,$idx),@T[1]);
+	&mov	(&DWP(8,$idx),@T[2]);
+	&mov	(&DWP(12,$idx),@T[3]);
+&function_end("Camellia_encrypt");
+}
+
+&function_begin_B("_x86_Camellia_encrypt");
+	&xor	(@T[0],&DWP(0,$key));	# ^=key[0-3]
+	&xor	(@T[1],&DWP(4,$key));
+	&xor	(@T[2],&DWP(8,$key));
+	&xor	(@T[3],&DWP(12,$key));
+	&mov	($idx,&DWP(16,$key));	# prefetch key[4]
+
+	&mov	($__s0,@T[0]);		# save s[0-3]
+	&mov	($__s1,@T[1]);
+	&mov	($__s2,@T[2]);
+	&mov	($__s3,@T[3]);
+
+&set_label("loop",16);
+	for ($i=0;$i<6;$i++) { Camellia_Feistel($i,16,4); }
+
+	&add	($key,16*4);
+	&cmp	($key,$__end);
+	&je	(&label("done"));
+
+	# @T[0-1] are preloaded, $idx is preloaded with key[0]
+	&and	($idx,@T[0]);
+	 &mov	 (@T[3],$__s3);
+	&rotl	($idx,1);
+	 &mov	 (@T[2],@T[3]);
+	&xor	(@T[1],$idx);
+	 &or	 (@T[2],&DWP(12,$key));
+	&mov	($__s1,@T[1]);		# s1^=LeftRotate(s0&key[0],1);
+	 &xor	 (@T[2],$__s2);
+
+	&mov	($idx,&DWP(4,$key));
+	 &mov	 ($__s2,@T[2]);		# s2^=s3|key[3];
+	&or	($idx,@T[1]);
+	 &and	 (@T[2],&DWP(8,$key));
+	&xor	(@T[0],$idx);
+	 &rotl	 (@T[2],1);
+	&mov	($__s0,@T[0]);		# s0^=s1|key[1];
+	 &xor	 (@T[3],@T[2]);
+	&mov	($idx,&DWP(16,$key));		# prefetch key[4]
+	 &mov	 ($__s3,@T[3]);		# s3^=LeftRotate(s2&key[2],1);
+	&jmp	(&label("loop"));
+
+&set_label("done",8);
+	&mov	(@T[2],@T[0]);		# SwapHalf
+	&mov	(@T[3],@T[1]);
+	&mov	(@T[0],$__s2);
+	&mov	(@T[1],$__s3);
+	&xor	(@T[0],$idx);		# $idx is preloaded with key[0]
+	&xor	(@T[1],&DWP(4,$key));
+	&xor	(@T[2],&DWP(8,$key));
+	&xor	(@T[3],&DWP(12,$key));
+	&ret	();
+&function_end_B("_x86_Camellia_encrypt");
+
+# void Camellia_DecryptBlock_Rounds(
+#		int grandRounds,
+#		const Byte ciphertext[],
+#		const KEY_TABLE_TYPE keyTable,
+#		Byte plaintext[])
+&function_begin("Camellia_DecryptBlock_Rounds");
+	&mov	("eax",&wparam(0));	# load grandRounds
+	&mov	($idx,&wparam(1));	# load ciphertext pointer
+	&mov	($key,&wparam(2));	# load key schedule pointer
+
+	&mov	("ebx","esp");
+	&sub	("esp",7*4);		# place for s[0-3],keyEnd,esp and ra
+	&and	("esp",-64);
+
+	# place stack frame just "above mod 1024" the key schedule
+	# this ensures that cache associativity of 2 suffices
+	&lea	("ecx",&DWP(-64-63,$key));
+	&sub	("ecx","esp");
+	&neg	("ecx");
+	&and	("ecx",0x3C0);	# modulo 1024, but aligned to cache-line
+	&sub	("esp","ecx");
+	&add	("esp",4);	# 4 is reserved for callee's return address
+
+	&shl	("eax",6);
+	&mov	(&DWP(4*4,"esp"),$key);	# save keyStart
+	&lea	($key,&DWP(0,$key,"eax"));
+	&mov	(&DWP(5*4,"esp"),"ebx");# save %esp
+
+	&call	(&label("pic_point"));
+	&set_label("pic_point");
+	&blindpop($Tbl);
+	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
+
+	&mov	(@T[0],&DWP(0,$idx));	# load ciphertext
+	&mov	(@T[1],&DWP(4,$idx));
+	&mov	(@T[2],&DWP(8,$idx));
+	&bswap	(@T[0]);
+	&mov	(@T[3],&DWP(12,$idx));
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+
+	&call	("_x86_Camellia_decrypt");
+
+	&mov	("esp",&DWP(5*4,"esp"));
+	&bswap	(@T[0]);
+	&mov	($idx,&wparam(3));	# load plaintext pointer
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+	&mov	(&DWP(0,$idx),@T[0]);	# write plaintext
+	&mov	(&DWP(4,$idx),@T[1]);
+	&mov	(&DWP(8,$idx),@T[2]);
+	&mov	(&DWP(12,$idx),@T[3]);
+&function_end("Camellia_DecryptBlock_Rounds");
+# V1.x API
+&function_begin_B("Camellia_DecryptBlock");
+	&mov	("eax",128);
+	&sub	("eax",&wparam(0));	# load keyBitLength
+	&mov	("eax",3);
+	&adc	("eax",0);		# keyBitLength==128?3:4
+	&mov	(&wparam(0),"eax");
+	&jmp	(&label("Camellia_DecryptBlock_Rounds"));
+&function_end_B("Camellia_DecryptBlock");
+
+if ($OPENSSL) {
+# void Camellia_decrypt(
+#		const unsigned char *in,
+#		unsigned char *out,
+#		const CAMELLIA_KEY *key)
+&function_begin("Camellia_decrypt");
+	&mov	($idx,&wparam(0));	# load ciphertext pointer
+	&mov	($key,&wparam(2));	# load key schedule pointer
+
+	&mov	("ebx","esp");
+	&sub	("esp",7*4);		# place for s[0-3],keyEnd,esp and ra
+	&and	("esp",-64);
+	&mov	("eax",&DWP(272,$key));	# load grandRounds counter
+
+	# place stack frame just "above mod 1024" the key schedule
+	# this ensures that cache associativity of 2 suffices
+	&lea	("ecx",&DWP(-64-63,$key));
+	&sub	("ecx","esp");
+	&neg	("ecx");
+	&and	("ecx",0x3C0);	# modulo 1024, but aligned to cache-line
+	&sub	("esp","ecx");
+	&add	("esp",4);	# 4 is reserved for callee's return address
+
+	&shl	("eax",6);
+	&mov	(&DWP(4*4,"esp"),$key);	# save keyStart
+	&lea	($key,&DWP(0,$key,"eax"));
+	&mov	(&DWP(5*4,"esp"),"ebx");# save %esp
+
+	&call	(&label("pic_point"));
+	&set_label("pic_point");
+	&blindpop($Tbl);
+	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
+
+	&mov	(@T[0],&DWP(0,$idx));	# load ciphertext
+	&mov	(@T[1],&DWP(4,$idx));
+	&mov	(@T[2],&DWP(8,$idx));
+	&bswap	(@T[0]);
+	&mov	(@T[3],&DWP(12,$idx));
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+
+	&call	("_x86_Camellia_decrypt");
+
+	&mov	("esp",&DWP(5*4,"esp"));
+	&bswap	(@T[0]);
+	&mov	($idx,&wparam(1));	# load plaintext pointer
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+	&mov	(&DWP(0,$idx),@T[0]);	# write plaintext
+	&mov	(&DWP(4,$idx),@T[1]);
+	&mov	(&DWP(8,$idx),@T[2]);
+	&mov	(&DWP(12,$idx),@T[3]);
+&function_end("Camellia_decrypt");
+}
+
+&function_begin_B("_x86_Camellia_decrypt");
+	&xor	(@T[0],&DWP(0,$key));	# ^=key[0-3]
+	&xor	(@T[1],&DWP(4,$key));
+	&xor	(@T[2],&DWP(8,$key));
+	&xor	(@T[3],&DWP(12,$key));
+	&mov	($idx,&DWP(-8,$key));	# prefetch key[-2]
+
+	&mov	($__s0,@T[0]);		# save s[0-3]
+	&mov	($__s1,@T[1]);
+	&mov	($__s2,@T[2]);
+	&mov	($__s3,@T[3]);
+
+&set_label("loop",16);
+	for ($i=0;$i<6;$i++) { Camellia_Feistel($i,-8,4); }
+
+	&sub	($key,16*4);
+	&cmp	($key,$__end);
+	&je	(&label("done"));
+
+	# @T[0-1] are preloaded, $idx is preloaded with key[2]
+	&and	($idx,@T[0]);
+	 &mov	 (@T[3],$__s3);
+	&rotl	($idx,1);
+	 &mov	 (@T[2],@T[3]);
+	&xor	(@T[1],$idx);
+	 &or	 (@T[2],&DWP(4,$key));
+	&mov	($__s1,@T[1]);		# s1^=LeftRotate(s0&key[0],1);
+	 &xor	 (@T[2],$__s2);
+
+	&mov	($idx,&DWP(12,$key));
+	 &mov	 ($__s2,@T[2]);		# s2^=s3|key[3];
+	&or	($idx,@T[1]);
+	 &and	 (@T[2],&DWP(0,$key));
+	&xor	(@T[0],$idx);
+	 &rotl	 (@T[2],1);
+	&mov	($__s0,@T[0]);		# s0^=s1|key[1];
+	 &xor	 (@T[3],@T[2]);
+	&mov	($idx,&DWP(-8,$key));	# prefetch key[4]
+	 &mov	 ($__s3,@T[3]);		# s3^=LeftRotate(s2&key[2],1);
+	&jmp	(&label("loop"));
+
+&set_label("done",8);
+	&mov	(@T[2],@T[0]);		# SwapHalf
+	&mov	(@T[3],@T[1]);
+	&mov	(@T[0],$__s2);
+	&mov	(@T[1],$__s3);
+	&xor	(@T[2],$idx);		# $idx is preloaded with key[2]
+	&xor	(@T[3],&DWP(12,$key));
+	&xor	(@T[0],&DWP(0,$key));
+	&xor	(@T[1],&DWP(4,$key));
+	&ret	();
+&function_end_B("_x86_Camellia_decrypt");
+
+# shld is very slow on Intel P4 family. Even on AMD it limits
+# instruction decode rate [because it's VectorPath] and consequently
+# performance. PIII, PM and Core[2] seem to be the only ones which
+# execute this code ~7% faster...
+sub __rotl128 {
+  my ($i0,$i1,$i2,$i3,$rot,$rnd,@T)=@_;
+
+    $rnd *= 2;
+    if ($rot) {
+	&mov	($idx,$i0);
+	&shld	($i0,$i1,$rot);
+	&shld	($i1,$i2,$rot);
+	&shld	($i2,$i3,$rot);
+	&shld	($i3,$idx,$rot);
+    }
+    &mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i0 eq @T[0]);
+    &mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i1 eq @T[0]);
+    &mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i2 eq @T[0]);
+    &mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i3 eq @T[0]);
+}
+
+# ... Implementing 128-bit rotate without shld gives >3x performance
+# improvement on P4, only ~7% degradation on other Intel CPUs and
+# not worse performance on AMD. This is therefore preferred.
+sub _rotl128 {
+  my ($i0,$i1,$i2,$i3,$rot,$rnd,@T)=@_;
+
+    $rnd *= 2;
+    if ($rot) {
+	&mov	($Tbl,$i0);
+	&shl	($i0,$rot);
+	&mov	($idx,$i1);
+	&shr	($idx,32-$rot);
+	&shl	($i1,$rot);
+	&or	($i0,$idx);
+	&mov	($idx,$i2);
+	&shl	($i2,$rot);
+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i0 eq @T[0]);
+	&shr	($idx,32-$rot);
+	&or	($i1,$idx);
+	&shr	($Tbl,32-$rot);
+	&mov	($idx,$i3);
+	&shr	($idx,32-$rot);
+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i1 eq @T[0]);
+	&shl	($i3,$rot);
+	&or	($i2,$idx);
+	&or	($i3,$Tbl);
+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i2 eq @T[0]);
+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i3 eq @T[0]);
+    } else {
+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i0 eq @T[0]);
+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i1 eq @T[0]);
+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i2 eq @T[0]);
+	&mov	(&DWP(-128+4*$rnd++,$key),shift(@T))	if ($i3 eq @T[0]);
+    }
+}
+
+sub _saveround {
+my ($rnd,$key,@T)=@_;
+my $bias=int(@T[0])?shift(@T):0;
+
+	&mov	(&DWP($bias+$rnd*8+0,$key),@T[0]);
+	&mov	(&DWP($bias+$rnd*8+4,$key),@T[1])	if ($#T>=1);
+	&mov	(&DWP($bias+$rnd*8+8,$key),@T[2])	if ($#T>=2);
+	&mov	(&DWP($bias+$rnd*8+12,$key),@T[3])	if ($#T>=3);
+}
+
+sub _loadround {
+my ($rnd,$key,@T)=@_;
+my $bias=int(@T[0])?shift(@T):0;
+
+	&mov	(@T[0],&DWP($bias+$rnd*8+0,$key));
+	&mov	(@T[1],&DWP($bias+$rnd*8+4,$key))	if ($#T>=1);
+	&mov	(@T[2],&DWP($bias+$rnd*8+8,$key))	if ($#T>=2);
+	&mov	(@T[3],&DWP($bias+$rnd*8+12,$key))	if ($#T>=3);
+}
+
+# void Camellia_Ekeygen(
+#		const int keyBitLength,
+#		const Byte *rawKey,
+#		KEY_TABLE_TYPE keyTable)
+&function_begin("Camellia_Ekeygen");
+{ my $step=0;
+
+	&stack_push(4);				# place for s[0-3]
+
+	&mov	($Tbl,&wparam(0));		# load arguments
+	&mov	($idx,&wparam(1));
+	&mov	($key,&wparam(2));
+
+	&mov	(@T[0],&DWP(0,$idx));		# load 0-127 bits
+	&mov	(@T[1],&DWP(4,$idx));
+	&mov	(@T[2],&DWP(8,$idx));
+	&mov	(@T[3],&DWP(12,$idx));
+
+	&bswap	(@T[0]);
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+
+	&_saveround	(0,$key,@T);		# KL<<<0
+
+	&cmp	($Tbl,128);
+	&je	(&label("1st128"));
+
+	&mov	(@T[0],&DWP(16,$idx));		# load 128-191 bits
+	&mov	(@T[1],&DWP(20,$idx));
+	&cmp	($Tbl,192);
+	&je	(&label("1st192"));
+	&mov	(@T[2],&DWP(24,$idx));		# load 192-255 bits
+	&mov	(@T[3],&DWP(28,$idx));
+	&jmp	(&label("1st256"));
+&set_label("1st192",4);
+	&mov	(@T[2],@T[0]);
+	&mov	(@T[3],@T[1]);
+	&not	(@T[2]);
+	&not	(@T[3]);
+&set_label("1st256",4);
+	&bswap	(@T[0]);
+	&bswap	(@T[1]);
+	&bswap	(@T[2]);
+	&bswap	(@T[3]);
+
+	&_saveround	(4,$key,@T);		# temporary storage for KR!
+
+	&xor	(@T[0],&DWP(0*8+0,$key));	# KR^KL
+	&xor	(@T[1],&DWP(0*8+4,$key));
+	&xor	(@T[2],&DWP(1*8+0,$key));
+	&xor	(@T[3],&DWP(1*8+4,$key));
+
+&set_label("1st128",4);
+	&call	(&label("pic_point"));
+	&set_label("pic_point");
+	&blindpop($Tbl);
+	&lea	($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
+	&lea	($key,&DWP(&label("Camellia_SIGMA")."-".&label("Camellia_SBOX"),$Tbl));
+
+	&mov	($idx,&DWP($step*8,$key));	# prefetch SIGMA[0]
+	&mov	(&swtmp(0),@T[0]);		# save s[0-3]
+	&mov	(&swtmp(1),@T[1]);
+	&mov	(&swtmp(2),@T[2]);
+	&mov	(&swtmp(3),@T[3]);
+	&Camellia_Feistel($step++);
+	&Camellia_Feistel($step++);
+	&mov	(@T[2],&swtmp(2));
+	&mov	(@T[3],&swtmp(3));
+
+	&mov	($idx,&wparam(2));
+	&xor	(@T[0],&DWP(0*8+0,$idx));	# ^KL
+	&xor	(@T[1],&DWP(0*8+4,$idx));
+	&xor	(@T[2],&DWP(1*8+0,$idx));
+	&xor	(@T[3],&DWP(1*8+4,$idx));
+
+	&mov	($idx,&DWP($step*8,$key));	# prefetch SIGMA[4]
+	&mov	(&swtmp(0),@T[0]);		# save s[0-3]
+	&mov	(&swtmp(1),@T[1]);
+	&mov	(&swtmp(2),@T[2]);
+	&mov	(&swtmp(3),@T[3]);
+	&Camellia_Feistel($step++);
+	&Camellia_Feistel($step++);
+	&mov	(@T[2],&swtmp(2));
+	&mov	(@T[3],&swtmp(3));
+
+	&mov	($idx,&wparam(0));
+	&cmp	($idx,128);
+	&jne	(&label("2nd256"));
+
+	&mov	($key,&wparam(2));
+	&lea	($key,&DWP(128,$key));		# size optimization
+
+	####### process KA
+	&_saveround	(2,$key,-128,@T);	# KA<<<0
+	&_rotl128	(@T,15,6,@T);		# KA<<<15
+	&_rotl128	(@T,15,8,@T);		# KA<<<(15+15=30)
+	&_rotl128	(@T,15,12,@T[0],@T[1]);	# KA<<<(30+15=45)
+	&_rotl128	(@T,15,14,@T);		# KA<<<(45+15=60)
+	push		(@T,shift(@T));		# rotl128(@T,32);
+	&_rotl128	(@T,2,20,@T);		# KA<<<(60+32+2=94)
+	&_rotl128	(@T,17,24,@T);		# KA<<<(94+17=111)
+
+	####### process KL
+	&_loadround	(0,$key,-128,@T);	# load KL
+	&_rotl128	(@T,15,4,@T);		# KL<<<15
+	&_rotl128	(@T,30,10,@T);		# KL<<<(15+30=45)
+	&_rotl128	(@T,15,13,@T[2],@T[3]);	# KL<<<(45+15=60)
+	&_rotl128	(@T,17,16,@T);		# KL<<<(60+17=77)
+	&_rotl128	(@T,17,18,@T);		# KL<<<(77+17=94)
+	&_rotl128	(@T,17,22,@T);		# KL<<<(94+17=111)
+
+	while (@T[0] ne "eax")			# restore order
+	{   unshift	(@T,pop(@T));   }
+
+	&mov	("eax",3);			# 3 grandRounds
+	&jmp	(&label("done"));
+
+&set_label("2nd256",16);
+	&mov	($idx,&wparam(2));
+	&_saveround	(6,$idx,@T);		# temporary storage for KA!
+
+	&xor	(@T[0],&DWP(4*8+0,$idx));	# KA^KR
+	&xor	(@T[1],&DWP(4*8+4,$idx));
+	&xor	(@T[2],&DWP(5*8+0,$idx));
+	&xor	(@T[3],&DWP(5*8+4,$idx));
+
+	&mov	($idx,&DWP($step*8,$key));	# prefetch SIGMA[8]
+	&mov	(&swtmp(0),@T[0]);		# save s[0-3]
+	&mov	(&swtmp(1),@T[1]);
+	&mov	(&swtmp(2),@T[2]);
+	&mov	(&swtmp(3),@T[3]);
+	&Camellia_Feistel($step++);
+	&Camellia_Feistel($step++);
+	&mov	(@T[2],&swtmp(2));
+	&mov	(@T[3],&swtmp(3));
+
+	&mov	($key,&wparam(2));
+	&lea	($key,&DWP(128,$key));		# size optimization
+
+	####### process KB
+	&_saveround	(2,$key,-128,@T);	# KB<<<0
+	&_rotl128	(@T,30,10,@T);		# KB<<<30
+	&_rotl128	(@T,30,20,@T);		# KB<<<(30+30=60)
+	push		(@T,shift(@T));		# rotl128(@T,32);
+	&_rotl128	(@T,19,32,@T);		# KB<<<(60+32+19=111)
+
+	####### process KR
+	&_loadround	(4,$key,-128,@T);	# load KR
+	&_rotl128	(@T,15,4,@T);		# KR<<<15
+	&_rotl128	(@T,15,8,@T);		# KR<<<(15+15=30)
+	&_rotl128	(@T,30,18,@T);		# KR<<<(30+30=60)
+	push		(@T,shift(@T));		# rotl128(@T,32);
+	&_rotl128	(@T,2,26,@T);		# KR<<<(60+32+2=94)
+
+	####### process KA
+	&_loadround	(6,$key,-128,@T);	# load KA
+	&_rotl128	(@T,15,6,@T);		# KA<<<15
+	&_rotl128	(@T,30,14,@T);		# KA<<<(15+30=45)
+	push		(@T,shift(@T));		# rotl128(@T,32);
+	&_rotl128	(@T,0,24,@T);		# KA<<<(45+32+0=77)
+	&_rotl128	(@T,17,28,@T);		# KA<<<(77+17=94)
+
+	####### process KL
+	&_loadround	(0,$key,-128,@T);	# load KL
+	push		(@T,shift(@T));		# rotl128(@T,32);
+	&_rotl128	(@T,13,12,@T);		# KL<<<(32+13=45)
+	&_rotl128	(@T,15,16,@T);		# KL<<<(45+15=60)
+	&_rotl128	(@T,17,22,@T);		# KL<<<(60+17=77)
+	push		(@T,shift(@T));		# rotl128(@T,32);
+	&_rotl128	(@T,2,30,@T);		# KL<<<(77+32+2=111)
+
+	while (@T[0] ne "eax")			# restore order
+	{   unshift	(@T,pop(@T));   }
+
+	&mov	("eax",4);			# 4 grandRounds
+&set_label("done");
+	&lea	("edx",&DWP(272-128,$key));	# end of key schedule
+	&stack_pop(4);
+}
+&function_end("Camellia_Ekeygen");
+
+if ($OPENSSL) {
+# int Camellia_set_key (
+#		const unsigned char *userKey,
+#		int bits,
+#		CAMELLIA_KEY *key)
+&function_begin_B("Camellia_set_key");
+	&push	("ebx");
+	&mov	("ecx",&wparam(0));	# pull arguments
+	&mov	("ebx",&wparam(1));
+	&mov	("edx",&wparam(2));
+
+	&mov	("eax",-1);
+	&test	("ecx","ecx");
+	&jz	(&label("done"));	# userKey==NULL?
+	&test	("edx","edx");
+	&jz	(&label("done"));	# key==NULL?
+
+	&mov	("eax",-2);
+	&cmp	("ebx",256);
+	&je	(&label("arg_ok"));	# bits==256?
+	&cmp	("ebx",192);
+	&je	(&label("arg_ok"));	# bits==192?
+	&cmp	("ebx",128);
+	&jne	(&label("done"));	# bits!=128?
+&set_label("arg_ok",4);
+
+	&push	("edx");		# push arguments
+	&push	("ecx");
+	&push	("ebx");
+	&call	("Camellia_Ekeygen");
+	&stack_pop(3);
+
+	# eax holds grandRounds and edx points at where to put it
+	&mov	(&DWP(0,"edx"),"eax");
+	&xor	("eax","eax");
+&set_label("done",4);
+	&pop	("ebx");
+	&ret	();
+&function_end_B("Camellia_set_key");
+}
+
+@SBOX=(
+112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
+ 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
+134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
+166,225, 57,202,213, 71, 93, 61,217,  1, 90,214, 81, 86,108, 77,
+139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
+223, 76,203,194, 52,126,118,  5,109,183,169, 49,209, 23,  4,215,
+ 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
+254, 68,207,178,195,181,122,145, 36,  8,232,168, 96,252,105, 80,
+170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
+ 16,196,  0, 72,163,247,117,219,138,  3,230,218,  9, 63,221,148,
+135, 92,131,  2,205, 74,144, 51,115,103,246,243,157,127,191,226,
+ 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
+233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
+120,152,  6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
+114,  7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
+ 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158);
+
+sub S1110 { my $i=shift; $i=@SBOX[$i]; return $i<<24|$i<<16|$i<<8; }
+sub S4404 { my $i=shift; $i=($i<<1|$i>>7)&0xff; $i=@SBOX[$i]; return $i<<24|$i<<16|$i; }	
+sub S0222 { my $i=shift; $i=@SBOX[$i]; $i=($i<<1|$i>>7)&0xff; return $i<<16|$i<<8|$i; }	
+sub S3033 { my $i=shift; $i=@SBOX[$i]; $i=($i>>1|$i<<7)&0xff; return $i<<24|$i<<8|$i; }	
+
+&set_label("Camellia_SIGMA",64);
+&data_word(
+    0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2,
+    0xc6ef372f, 0xe94f82be, 0x54ff53a5, 0xf1d36f1c,
+    0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd,
+    0,          0,          0,          0);
+&set_label("Camellia_SBOX",64);
+# tables are interleaved, remember?
+for ($i=0;$i<256;$i++) { &data_word(&S1110($i),&S4404($i)); }
+for ($i=0;$i<256;$i++) { &data_word(&S0222($i),&S3033($i)); }
+
+# void Camellia_cbc_encrypt (const void char *inp, unsigned char *out,
+#			size_t length, const CAMELLIA_KEY *key,
+#			unsigned char *ivp,const int enc);
+{
+# stack frame layout
+#             -4(%esp)		# return address	 0(%esp)
+#              0(%esp)		# s0			 4(%esp)
+#              4(%esp)		# s1			 8(%esp)
+#              8(%esp)		# s2			12(%esp)
+#             12(%esp)		# s3			16(%esp)
+#             16(%esp)		# end of key schedule	20(%esp)
+#             20(%esp)		# %esp backup
+my $_inp=&DWP(24,"esp");	#copy of wparam(0)
+my $_out=&DWP(28,"esp");	#copy of wparam(1)
+my $_len=&DWP(32,"esp");	#copy of wparam(2)
+my $_key=&DWP(36,"esp");	#copy of wparam(3)
+my $_ivp=&DWP(40,"esp");	#copy of wparam(4)
+my $ivec=&DWP(44,"esp");	#ivec[16]
+my $_tmp=&DWP(44,"esp");	#volatile variable [yes, aliases with ivec]
+my ($s0,$s1,$s2,$s3) = @T;
+
+&function_begin("Camellia_cbc_encrypt");
+	&mov	($s2 eq "ecx"? $s2 : "",&wparam(2));	# load len
+	&cmp	($s2,0);
+	&je	(&label("enc_out"));
+
+	&pushf	();
+	&cld	();
+
+	&mov	($s0,&wparam(0));	# load inp
+	&mov	($s1,&wparam(1));	# load out
+	#&mov	($s2,&wparam(2));	# load len
+	&mov	($s3,&wparam(3));	# load key
+	&mov	($Tbl,&wparam(4));	# load ivp
+
+	# allocate aligned stack frame...
+	&lea	($idx,&DWP(-64,"esp"));
+	&and	($idx,-64);
+
+	# place stack frame just "above mod 1024" the key schedule
+	# this ensures that cache associativity of 2 suffices
+	&lea	($key,&DWP(-64-63,$s3));
+	&sub	($key,$idx);
+	&neg	($key);
+	&and	($key,0x3C0);	# modulo 1024, but aligned to cache-line
+	&sub	($idx,$key);
+
+	&mov	($key,&wparam(5));	# load enc
+
+	&exch	("esp",$idx);
+	&add	("esp",4);		# reserve for return address!
+	&mov	($_esp,$idx);		# save %esp
+
+	&mov	($_inp,$s0);		# save copy of inp
+	&mov	($_out,$s1);		# save copy of out
+	&mov	($_len,$s2);		# save copy of len
+	&mov	($_key,$s3);		# save copy of key
+	&mov	($_ivp,$Tbl);		# save copy of ivp
+
+	&call   (&label("pic_point"));	# make it PIC!
+	&set_label("pic_point");
+	&blindpop($Tbl);
+	&lea    ($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl));
+
+	&mov	($idx,32);
+	&set_label("prefetch_sbox",4);
+		&mov	($s0,&DWP(0,$Tbl));
+		&mov	($s1,&DWP(32,$Tbl));
+		&mov	($s2,&DWP(64,$Tbl));
+		&mov	($s3,&DWP(96,$Tbl));
+		&lea	($Tbl,&DWP(128,$Tbl));
+		&dec	($idx);
+	&jnz	(&label("prefetch_sbox"));
+	&mov	($s0,$_key);
+	&sub	($Tbl,4096);
+	&mov	($idx,$_inp);
+	&mov	($s3,&DWP(272,$s0));		# load grandRounds
+
+	&cmp	($key,0);
+	&je	(&label("DECRYPT"));
+
+	&mov	($s2,$_len);
+	&mov	($key,$_ivp);
+	&shl	($s3,6);
+	&lea	($s3,&DWP(0,$s0,$s3));
+	&mov	($_end,$s3);
+
+	&test	($s2,0xFFFFFFF0);
+	&jz	(&label("enc_tail"));		# short input...
+
+	&mov	($s0,&DWP(0,$key));		# load iv
+	&mov	($s1,&DWP(4,$key));
+
+	&set_label("enc_loop",4);
+		&mov	($s2,&DWP(8,$key));
+		&mov	($s3,&DWP(12,$key));
+
+		&xor	($s0,&DWP(0,$idx));	# xor input data
+		&xor	($s1,&DWP(4,$idx));
+		&xor	($s2,&DWP(8,$idx));
+		&bswap	($s0);
+		&xor	($s3,&DWP(12,$idx));
+		&bswap	($s1);
+		&mov	($key,$_key);		# load key
+		&bswap	($s2);
+		&bswap	($s3);
+
+		&call	("_x86_Camellia_encrypt");
+
+		&mov	($idx,$_inp);		# load inp
+		&mov	($key,$_out);		# load out
+
+		&bswap	($s0);
+		&bswap	($s1);
+		&bswap	($s2);
+		&mov	(&DWP(0,$key),$s0);	# save output data
+		&bswap	($s3);
+		&mov	(&DWP(4,$key),$s1);
+		&mov	(&DWP(8,$key),$s2);
+		&mov	(&DWP(12,$key),$s3);
+
+		&mov	($s2,$_len);		# load len
+
+		&lea	($idx,&DWP(16,$idx));
+		&mov	($_inp,$idx);		# save inp
+
+		&lea	($s3,&DWP(16,$key));
+		&mov	($_out,$s3);		# save out
+
+		&sub	($s2,16);
+		&test	($s2,0xFFFFFFF0);
+		&mov	($_len,$s2);		# save len
+	&jnz	(&label("enc_loop"));
+	&test	($s2,15);
+	&jnz	(&label("enc_tail"));
+	&mov	($idx,$_ivp);		# load ivp
+	&mov	($s2,&DWP(8,$key));	# restore last dwords
+	&mov	($s3,&DWP(12,$key));
+	&mov	(&DWP(0,$idx),$s0);	# save ivec
+	&mov	(&DWP(4,$idx),$s1);
+	&mov	(&DWP(8,$idx),$s2);
+	&mov	(&DWP(12,$idx),$s3);
+
+	&mov	("esp",$_esp);
+	&popf	();
+    &set_label("enc_out");
+	&function_end_A();
+	&pushf	();			# kludge, never executed
+
+    &set_label("enc_tail",4);
+	&mov	($s0,$key eq "edi" ? $key : "");
+	&mov	($key,$_out);			# load out
+	&push	($s0);				# push ivp
+	&mov	($s1,16);
+	&sub	($s1,$s2);
+	&cmp	($key,$idx);			# compare with inp
+	&je	(&label("enc_in_place"));
+	&align	(4);
+	&data_word(0xA4F3F689);	# rep movsb	# copy input
+	&jmp	(&label("enc_skip_in_place"));
+    &set_label("enc_in_place");
+	&lea	($key,&DWP(0,$key,$s2));
+    &set_label("enc_skip_in_place");
+	&mov	($s2,$s1);
+	&xor	($s0,$s0);
+	&align	(4);
+	&data_word(0xAAF3F689);	# rep stosb	# zero tail
+	&pop	($key);				# pop ivp
+
+	&mov	($idx,$_out);			# output as input
+	&mov	($s0,&DWP(0,$key));
+	&mov	($s1,&DWP(4,$key));
+	&mov	($_len,16);			# len=16
+	&jmp	(&label("enc_loop"));		# one more spin...
+
+#----------------------------- DECRYPT -----------------------------#
+&set_label("DECRYPT",16);
+	&shl	($s3,6);
+	&lea	($s3,&DWP(0,$s0,$s3));
+	&mov	($_end,$s0);
+	&mov	($_key,$s3);
+
+	&cmp	($idx,$_out);
+	&je	(&label("dec_in_place"));	# in-place processing...
+
+	&mov	($key,$_ivp);			# load ivp
+	&mov	($_tmp,$key);
+
+	&set_label("dec_loop",4);
+		&mov	($s0,&DWP(0,$idx));	# read input
+		&mov	($s1,&DWP(4,$idx));
+		&mov	($s2,&DWP(8,$idx));
+		&bswap	($s0);
+		&mov	($s3,&DWP(12,$idx));
+		&bswap	($s1);
+		&mov	($key,$_key);		# load key
+		&bswap	($s2);
+		&bswap	($s3);
+
+		&call	("_x86_Camellia_decrypt");
+
+		&mov	($key,$_tmp);		# load ivp
+		&mov	($idx,$_len);		# load len
+
+		&bswap	($s0);
+		&bswap	($s1);
+		&bswap	($s2);
+		&xor	($s0,&DWP(0,$key));	# xor iv
+		&bswap	($s3);
+		&xor	($s1,&DWP(4,$key));
+		&xor	($s2,&DWP(8,$key));
+		&xor	($s3,&DWP(12,$key));
+
+		&sub	($idx,16);
+		&jc	(&label("dec_partial"));
+		&mov	($_len,$idx);		# save len
+		&mov	($idx,$_inp);		# load inp
+		&mov	($key,$_out);		# load out
+
+		&mov	(&DWP(0,$key),$s0);	# write output
+		&mov	(&DWP(4,$key),$s1);
+		&mov	(&DWP(8,$key),$s2);
+		&mov	(&DWP(12,$key),$s3);
+
+		&mov	($_tmp,$idx);		# save ivp
+		&lea	($idx,&DWP(16,$idx));
+		&mov	($_inp,$idx);		# save inp
+
+		&lea	($key,&DWP(16,$key));
+		&mov	($_out,$key);		# save out
+
+	&jnz	(&label("dec_loop"));
+	&mov	($key,$_tmp);		# load temp ivp
+    &set_label("dec_end");
+	&mov	($idx,$_ivp);		# load user ivp
+	&mov	($s0,&DWP(0,$key));	# load iv
+	&mov	($s1,&DWP(4,$key));
+	&mov	($s2,&DWP(8,$key));
+	&mov	($s3,&DWP(12,$key));
+	&mov	(&DWP(0,$idx),$s0);	# copy back to user
+	&mov	(&DWP(4,$idx),$s1);
+	&mov	(&DWP(8,$idx),$s2);
+	&mov	(&DWP(12,$idx),$s3);
+	&jmp	(&label("dec_out"));
+
+    &set_label("dec_partial",4);
+	&lea	($key,$ivec);
+	&mov	(&DWP(0,$key),$s0);	# dump output to stack
+	&mov	(&DWP(4,$key),$s1);
+	&mov	(&DWP(8,$key),$s2);
+	&mov	(&DWP(12,$key),$s3);
+	&lea	($s2 eq "ecx" ? $s2 : "",&DWP(16,$idx));
+	&mov	($idx eq "esi" ? $idx : "",$key);
+	&mov	($key eq "edi" ? $key : "",$_out);	# load out
+	&data_word(0xA4F3F689);	# rep movsb		# copy output
+	&mov	($key,$_inp);				# use inp as temp ivp
+	&jmp	(&label("dec_end"));
+
+    &set_label("dec_in_place",4);
+	&set_label("dec_in_place_loop");
+		&lea	($key,$ivec);
+		&mov	($s0,&DWP(0,$idx));	# read input
+		&mov	($s1,&DWP(4,$idx));
+		&mov	($s2,&DWP(8,$idx));
+		&mov	($s3,&DWP(12,$idx));
+
+		&mov	(&DWP(0,$key),$s0);	# copy to temp
+		&mov	(&DWP(4,$key),$s1);
+		&mov	(&DWP(8,$key),$s2);
+		&bswap	($s0);
+		&mov	(&DWP(12,$key),$s3);
+		&bswap	($s1);
+		&mov	($key,$_key);		# load key
+		&bswap	($s2);
+		&bswap	($s3);
+
+		&call	("_x86_Camellia_decrypt");
+
+		&mov	($key,$_ivp);		# load ivp
+		&mov	($idx,$_out);		# load out
+
+		&bswap	($s0);
+		&bswap	($s1);
+		&bswap	($s2);
+		&xor	($s0,&DWP(0,$key));	# xor iv
+		&bswap	($s3);
+		&xor	($s1,&DWP(4,$key));
+		&xor	($s2,&DWP(8,$key));
+		&xor	($s3,&DWP(12,$key));
+
+		&mov	(&DWP(0,$idx),$s0);	# write output
+		&mov	(&DWP(4,$idx),$s1);
+		&mov	(&DWP(8,$idx),$s2);
+		&mov	(&DWP(12,$idx),$s3);
+
+		&lea	($idx,&DWP(16,$idx));
+		&mov	($_out,$idx);		# save out
+
+		&lea	($idx,$ivec);
+		&mov	($s0,&DWP(0,$idx));	# read temp
+		&mov	($s1,&DWP(4,$idx));
+		&mov	($s2,&DWP(8,$idx));
+		&mov	($s3,&DWP(12,$idx));
+
+		&mov	(&DWP(0,$key),$s0);	# copy iv
+		&mov	(&DWP(4,$key),$s1);
+		&mov	(&DWP(8,$key),$s2);
+		&mov	(&DWP(12,$key),$s3);
+
+		&mov	($idx,$_inp);		# load inp
+
+		&lea	($idx,&DWP(16,$idx));
+		&mov	($_inp,$idx);		# save inp
+
+		&mov	($s2,$_len);		# load len
+		&sub	($s2,16);
+		&jc	(&label("dec_in_place_partial"));
+		&mov	($_len,$s2);		# save len
+	&jnz	(&label("dec_in_place_loop"));
+	&jmp	(&label("dec_out"));
+
+    &set_label("dec_in_place_partial",4);
+	# one can argue if this is actually required...
+	&mov	($key eq "edi" ? $key : "",$_out);
+	&lea	($idx eq "esi" ? $idx : "",$ivec);
+	&lea	($key,&DWP(0,$key,$s2));
+	&lea	($idx,&DWP(16,$idx,$s2));
+	&neg	($s2 eq "ecx" ? $s2 : "");
+	&data_word(0xA4F3F689);	# rep movsb	# restore tail
+
+    &set_label("dec_out",4);
+    &mov	("esp",$_esp);
+    &popf	();
+&function_end("Camellia_cbc_encrypt");
+}
+
+&asciz("Camellia for x86 by <appro@openssl.org>");
+
+&asm_finish();
diff --git a/crypto/camellia/asm/cmll-x86_64.pl b/crypto/camellia/asm/cmll-x86_64.pl
new file mode 100644
index 0000000..c683646
--- /dev/null
+++ b/crypto/camellia/asm/cmll-x86_64.pl
@@ -0,0 +1,1080 @@
+#!/usr/bin/env perl
+
+# ====================================================================
+# Copyright (c) 2008 Andy Polyakov <appro@openssl.org>
+#
+# This module may be used under the terms of either the GNU General
+# Public License version 2 or later, the GNU Lesser General Public
+# License version 2.1 or later, the Mozilla Public License version
+# 1.1 or the BSD License. The exact terms of either license are
+# distributed along with this module. For further details see
+# http://www.openssl.org/~appro/camellia/.
+# ====================================================================
+
+# Performance in cycles per processed byte (less is better) in
+# 'openssl speed ...' benchmark:
+#
+#			AMD64	Core2	EM64T
+# -evp camellia-128-ecb	16.7	21.0	22.7
+# + over gcc 3.4.6	+25%	+5%	0%
+#
+# camellia-128-cbc	15.7	20.4	21.1
+#
+# 128-bit key setup	128	216	205	cycles/key
+# + over gcc 3.4.6	+54%	+39%	+15%
+#
+# Numbers in "+" rows represent performance improvement over compiler
+# generated code. Key setup timings are impressive on AMD and Core2
+# thanks to 64-bit operations being covertly deployed. Improvement on
+# EM64T, pre-Core2 Intel x86_64 CPU, is not as impressive, because it
+# apparently emulates some of 64-bit operations in [32-bit] microcode.
+
+$flavour = shift;
+$output  = shift;
+if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+
+$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
+( $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";
+
+sub hi() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1h/;    $r; }
+sub lo() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/;
+                        $r =~ s/%[er]([sd]i)/%\1l/;
+                        $r =~ s/%(r[0-9]+)[d]?/%\1b/;   $r; }
+
+$t0="%eax";$t1="%ebx";$t2="%ecx";$t3="%edx";
+@S=("%r8d","%r9d","%r10d","%r11d");
+$i0="%esi";
+$i1="%edi";
+$Tbl="%rbp";	# size optimization
+$inp="%r12";
+$out="%r13";
+$key="%r14";
+$keyend="%r15";
+$arg0d=$win64?"%ecx":"%edi";
+
+# const unsigned int Camellia_SBOX[4][256];
+# Well, sort of... Camellia_SBOX[0][] is interleaved with [1][],
+# and [2][] - with [3][]. This is done to minimize code size.
+$SBOX1_1110=0;		# Camellia_SBOX[0]
+$SBOX4_4404=4;		# Camellia_SBOX[1]
+$SBOX2_0222=2048;	# Camellia_SBOX[2]
+$SBOX3_3033=2052;	# Camellia_SBOX[3]
+
+sub Camellia_Feistel {
+my $i=@_[0];
+my $seed=defined(@_[1])?@_[1]:0;
+my $scale=$seed<0?-8:8;
+my $j=($i&1)*2;
+my $s0=@S[($j)%4],$s1=@S[($j+1)%4],$s2=@S[($j+2)%4],$s3=@S[($j+3)%4];
+
+$code.=<<___;
+	xor	$s0,$t0				# t0^=key[0]
+	xor	$s1,$t1				# t1^=key[1]
+	movz	`&hi("$t0")`,$i0		# (t0>>8)&0xff
+	movz	`&lo("$t1")`,$i1		# (t1>>0)&0xff
+	mov	$SBOX3_3033($Tbl,$i0,8),$t3	# t3=SBOX3_3033[0]
+	mov	$SBOX1_1110($Tbl,$i1,8),$t2	# t2=SBOX1_1110[1]
+	movz	`&lo("$t0")`,$i0		# (t0>>0)&0xff
+	shr	\$16,$t0
+	movz	`&hi("$t1")`,$i1		# (t1>>8)&0xff
+	xor	$SBOX4_4404($Tbl,$i0,8),$t3	# t3^=SBOX4_4404[0]
+	shr	\$16,$t1
+	xor	$SBOX4_4404($Tbl,$i1,8),$t2	# t2^=SBOX4_4404[1]
+	movz	`&hi("$t0")`,$i0		# (t0>>24)&0xff
+	movz	`&lo("$t1")`,$i1		# (t1>>16)&0xff
+	xor	$SBOX1_1110($Tbl,$i0,8),$t3	# t3^=SBOX1_1110[0]
+	xor	$SBOX3_3033($Tbl,$i1,8),$t2	# t2^=SBOX3_3033[1]
+	movz	`&lo("$t0")`,$i0		# (t0>>16)&0xff
+	movz	`&hi("$t1")`,$i1		# (t1>>24)&0xff
+	xor	$SBOX2_0222($Tbl,$i0,8),$t3	# t3^=SBOX2_0222[0]
+	xor	$SBOX2_0222($Tbl,$i1,8),$t2	# t2^=SBOX2_0222[1]
+	mov	`$seed+($i+1)*$scale`($key),$t1	# prefetch key[i+1]
+	mov	`$seed+($i+1)*$scale+4`($key),$t0
+	xor	$t3,$t2				# t2^=t3
+	ror	\$8,$t3				# t3=RightRotate(t3,8)
+	xor	$t2,$s2
+	xor	$t2,$s3
+	xor	$t3,$s3
+___
+}
+
+# void Camellia_EncryptBlock_Rounds(
+#		int grandRounds,
+#		const Byte plaintext[],
+#		const KEY_TABLE_TYPE keyTable,
+#		Byte ciphertext[])
+$code=<<___;
+.text
+
+# V1.x API
+.globl	Camellia_EncryptBlock
+.type	Camellia_EncryptBlock,\@abi-omnipotent
+.align	16
+Camellia_EncryptBlock:
+	movl	\$128,%eax
+	subl	$arg0d,%eax
+	movl	\$3,$arg0d
+	adcl	\$0,$arg0d	# keyBitLength==128?3:4
+	jmp	.Lenc_rounds
+.size	Camellia_EncryptBlock,.-Camellia_EncryptBlock
+# V2
+.globl	Camellia_EncryptBlock_Rounds
+.type	Camellia_EncryptBlock_Rounds,\@function,4
+.align	16
+.Lenc_rounds:
+Camellia_EncryptBlock_Rounds:
+	push	%rbx
+	push	%rbp
+	push	%r13
+	push	%r14
+	push	%r15
+.Lenc_prologue:
+
+	#mov	%rsi,$inp		# put away arguments
+	mov	%rcx,$out
+	mov	%rdx,$key
+
+	shl	\$6,%edi		# process grandRounds
+	lea	.LCamellia_SBOX(%rip),$Tbl
+	lea	($key,%rdi),$keyend
+
+	mov	0(%rsi),@S[0]		# load plaintext
+	mov	4(%rsi),@S[1]
+	mov	8(%rsi),@S[2]
+	bswap	@S[0]
+	mov	12(%rsi),@S[3]
+	bswap	@S[1]
+	bswap	@S[2]
+	bswap	@S[3]
+
+	call	_x86_64_Camellia_encrypt
+
+	bswap	@S[0]
+	bswap	@S[1]
+	bswap	@S[2]
+	mov	@S[0],0($out)
+	bswap	@S[3]
+	mov	@S[1],4($out)
+	mov	@S[2],8($out)
+	mov	@S[3],12($out)
+
+	mov	0(%rsp),%r15
+	mov	8(%rsp),%r14
+	mov	16(%rsp),%r13
+	mov	24(%rsp),%rbp
+	mov	32(%rsp),%rbx
+	lea	40(%rsp),%rsp
+.Lenc_epilogue:
+	ret
+.size	Camellia_EncryptBlock_Rounds,.-Camellia_EncryptBlock_Rounds
+
+.type	_x86_64_Camellia_encrypt,\@abi-omnipotent
+.align	16
+_x86_64_Camellia_encrypt:
+	xor	0($key),@S[1]
+	xor	4($key),@S[0]		# ^=key[0-3]
+	xor	8($key),@S[3]
+	xor	12($key),@S[2]
+.align	16
+.Leloop:
+	mov	16($key),$t1		# prefetch key[4-5]
+	mov	20($key),$t0
+
+___
+	for ($i=0;$i<6;$i++) { Camellia_Feistel($i,16); }
+$code.=<<___;
+	lea	16*4($key),$key
+	cmp	$keyend,$key
+	mov	8($key),$t3		# prefetch key[2-3]
+	mov	12($key),$t2
+	je	.Ledone
+
+	and	@S[0],$t0
+	or	@S[3],$t3
+	rol	\$1,$t0
+	xor	$t3,@S[2]		# s2^=s3|key[3];
+	xor	$t0,@S[1]		# s1^=LeftRotate(s0&key[0],1);
+	and	@S[2],$t2
+	or	@S[1],$t1
+	rol	\$1,$t2
+	xor	$t1,@S[0]		# s0^=s1|key[1];
+	xor	$t2,@S[3]		# s3^=LeftRotate(s2&key[2],1);
+	jmp	.Leloop
+
+.align	16
+.Ledone:
+	xor	@S[2],$t0		# SwapHalf
+	xor	@S[3],$t1
+	xor	@S[0],$t2
+	xor	@S[1],$t3
+
+	mov	$t0,@S[0]
+	mov	$t1,@S[1]
+	mov	$t2,@S[2]
+	mov	$t3,@S[3]
+
+	.byte	0xf3,0xc3		# rep ret
+.size	_x86_64_Camellia_encrypt,.-_x86_64_Camellia_encrypt
+
+# V1.x API
+.globl	Camellia_DecryptBlock
+.type	Camellia_DecryptBlock,\@abi-omnipotent
+.align	16
+Camellia_DecryptBlock:
+	movl	\$128,%eax
+	subl	$arg0d,%eax
+	movl	\$3,$arg0d
+	adcl	\$0,$arg0d	# keyBitLength==128?3:4
+	jmp	.Ldec_rounds
+.size	Camellia_DecryptBlock,.-Camellia_DecryptBlock
+# V2
+.globl	Camellia_DecryptBlock_Rounds
+.type	Camellia_DecryptBlock_Rounds,\@function,4
+.align	16
+.Ldec_rounds:
+Camellia_DecryptBlock_Rounds:
+	push	%rbx
+	push	%rbp
+	push	%r13
+	push	%r14
+	push	%r15
+.Ldec_prologue:
+
+	#mov	%rsi,$inp		# put away arguments
+	mov	%rcx,$out
+	mov	%rdx,$keyend
+
+	shl	\$6,%edi		# process grandRounds
+	lea	.LCamellia_SBOX(%rip),$Tbl
+	lea	($keyend,%rdi),$key
+
+	mov	0(%rsi),@S[0]		# load plaintext
+	mov	4(%rsi),@S[1]
+	mov	8(%rsi),@S[2]
+	bswap	@S[0]
+	mov	12(%rsi),@S[3]
+	bswap	@S[1]
+	bswap	@S[2]
+	bswap	@S[3]
+
+	call	_x86_64_Camellia_decrypt
+
+	bswap	@S[0]
+	bswap	@S[1]
+	bswap	@S[2]
+	mov	@S[0],0($out)
+	bswap	@S[3]
+	mov	@S[1],4($out)
+	mov	@S[2],8($out)
+	mov	@S[3],12($out)
+
+	mov	0(%rsp),%r15
+	mov	8(%rsp),%r14
+	mov	16(%rsp),%r13
+	mov	24(%rsp),%rbp
+	mov	32(%rsp),%rbx
+	lea	40(%rsp),%rsp
+.Ldec_epilogue:
+	ret
+.size	Camellia_DecryptBlock_Rounds,.-Camellia_DecryptBlock_Rounds
+
+.type	_x86_64_Camellia_decrypt,\@abi-omnipotent
+.align	16
+_x86_64_Camellia_decrypt:
+	xor	0($key),@S[1]
+	xor	4($key),@S[0]		# ^=key[0-3]
+	xor	8($key),@S[3]
+	xor	12($key),@S[2]
+.align	16
+.Ldloop:
+	mov	-8($key),$t1		# prefetch key[4-5]
+	mov	-4($key),$t0
+
+___
+	for ($i=0;$i<6;$i++) { Camellia_Feistel($i,-8); }
+$code.=<<___;
+	lea	-16*4($key),$key
+	cmp	$keyend,$key
+	mov	0($key),$t3		# prefetch key[2-3]
+	mov	4($key),$t2
+	je	.Lddone
+
+	and	@S[0],$t0
+	or	@S[3],$t3
+	rol	\$1,$t0
+	xor	$t3,@S[2]		# s2^=s3|key[3];
+	xor	$t0,@S[1]		# s1^=LeftRotate(s0&key[0],1);
+	and	@S[2],$t2
+	or	@S[1],$t1
+	rol	\$1,$t2
+	xor	$t1,@S[0]		# s0^=s1|key[1];
+	xor	$t2,@S[3]		# s3^=LeftRotate(s2&key[2],1);
+
+	jmp	.Ldloop
+
+.align	16
+.Lddone:
+	xor	@S[2],$t2
+	xor	@S[3],$t3
+	xor	@S[0],$t0
+	xor	@S[1],$t1
+
+	mov	$t2,@S[0]		# SwapHalf
+	mov	$t3,@S[1]
+	mov	$t0,@S[2]
+	mov	$t1,@S[3]
+
+	.byte	0xf3,0xc3		# rep ret
+.size	_x86_64_Camellia_decrypt,.-_x86_64_Camellia_decrypt
+___
+
+sub _saveround {
+my ($rnd,$key,@T)=@_;
+my $bias=int(@T[0])?shift(@T):0;
+
+    if ($#T==3) {
+	$code.=<<___;
+	mov	@T[1],`$bias+$rnd*8+0`($key)
+	mov	@T[0],`$bias+$rnd*8+4`($key)
+	mov	@T[3],`$bias+$rnd*8+8`($key)
+	mov	@T[2],`$bias+$rnd*8+12`($key)
+___
+    } else {
+	$code.="	mov	@T[0],`$bias+$rnd*8+0`($key)\n";
+	$code.="	mov	@T[1],`$bias+$rnd*8+8`($key)\n"	if ($#T>=1);
+    }
+}
+
+sub _loadround {
+my ($rnd,$key,@T)=@_;
+my $bias=int(@T[0])?shift(@T):0;
+
+$code.="	mov	`$bias+$rnd*8+0`($key),@T[0]\n";
+$code.="	mov	`$bias+$rnd*8+8`($key),@T[1]\n"	if ($#T>=1);
+}
+
+# shld is very slow on Intel EM64T family. Even on AMD it limits
+# instruction decode rate [because it's VectorPath] and consequently
+# performance...
+sub __rotl128 {
+my ($i0,$i1,$rot)=@_;
+
+    if ($rot) {
+	$code.=<<___;
+	mov	$i0,%r11
+	shld	\$$rot,$i1,$i0
+	shld	\$$rot,%r11,$i1
+___
+    }
+}
+
+# ... Implementing 128-bit rotate without shld gives 80% better
+# performance EM64T, +15% on AMD64 and only ~7% degradation on
+# Core2. This is therefore preferred.
+sub _rotl128 {
+my ($i0,$i1,$rot)=@_;
+
+    if ($rot) {
+	$code.=<<___;
+	mov	$i0,%r11
+	shl	\$$rot,$i0
+	mov	$i1,%r9
+	shr	\$`64-$rot`,%r9
+	shr	\$`64-$rot`,%r11
+	or	%r9,$i0
+	shl	\$$rot,$i1
+	or	%r11,$i1
+___
+    }
+}
+
+{ my $step=0;
+
+$code.=<<___;
+.globl	Camellia_Ekeygen
+.type	Camellia_Ekeygen,\@function,3
+.align	16
+Camellia_Ekeygen:
+	push	%rbx
+	push	%rbp
+	push	%r13
+	push	%r14
+	push	%r15
+.Lkey_prologue:
+
+	mov	%rdi,$keyend		# put away arguments, keyBitLength
+	mov	%rdx,$out		# keyTable
+
+	mov	0(%rsi),@S[0]		# load 0-127 bits
+	mov	4(%rsi),@S[1]
+	mov	8(%rsi),@S[2]
+	mov	12(%rsi),@S[3]
+
+	bswap	@S[0]
+	bswap	@S[1]
+	bswap	@S[2]
+	bswap	@S[3]
+___
+	&_saveround	(0,$out,@S);	# KL<<<0
+$code.=<<___;
+	cmp	\$128,$keyend		# check keyBitLength
+	je	.L1st128
+
+	mov	16(%rsi),@S[0]		# load 128-191 bits
+	mov	20(%rsi),@S[1]
+	cmp	\$192,$keyend
+	je	.L1st192
+	mov	24(%rsi),@S[2]		# load 192-255 bits
+	mov	28(%rsi),@S[3]
+	jmp	.L1st256
+.L1st192:
+	mov	@S[0],@S[2]
+	mov	@S[1],@S[3]
+	not	@S[2]
+	not	@S[3]
+.L1st256:
+	bswap	@S[0]
+	bswap	@S[1]
+	bswap	@S[2]
+	bswap	@S[3]
+___
+	&_saveround	(4,$out,@S);	# temp storage for KR!
+$code.=<<___;
+	xor	0($out),@S[1]		# KR^KL
+	xor	4($out),@S[0]
+	xor	8($out),@S[3]
+	xor	12($out),@S[2]
+
+.L1st128:
+	lea	.LCamellia_SIGMA(%rip),$key
+	lea	.LCamellia_SBOX(%rip),$Tbl
+
+	mov	0($key),$t1
+	mov	4($key),$t0
+___
+	&Camellia_Feistel($step++);
+	&Camellia_Feistel($step++);
+$code.=<<___;
+	xor	0($out),@S[1]		# ^KL
+	xor	4($out),@S[0]
+	xor	8($out),@S[3]
+	xor	12($out),@S[2]
+___
+	&Camellia_Feistel($step++);
+	&Camellia_Feistel($step++);
+$code.=<<___;
+	cmp	\$128,$keyend
+	jne	.L2nd256
+
+	lea	128($out),$out		# size optimization
+	shl	\$32,%r8		# @S[0]||
+	shl	\$32,%r10		# @S[2]||
+	or	%r9,%r8			# ||@S[1]
+	or	%r11,%r10		# ||@S[3]
+___
+	&_loadround	(0,$out,-128,"%rax","%rbx");	# KL
+	&_saveround	(2,$out,-128,"%r8","%r10");	# KA<<<0
+	&_rotl128	("%rax","%rbx",15);
+	&_saveround	(4,$out,-128,"%rax","%rbx");	# KL<<<15
+	&_rotl128	("%r8","%r10",15);
+	&_saveround	(6,$out,-128,"%r8","%r10");	# KA<<<15
+	&_rotl128	("%r8","%r10",15);		# 15+15=30
+	&_saveround	(8,$out,-128,"%r8","%r10");	# KA<<<30
+	&_rotl128	("%rax","%rbx",30);		# 15+30=45
+	&_saveround	(10,$out,-128,"%rax","%rbx");	# KL<<<45
+	&_rotl128	("%r8","%r10",15);		# 30+15=45
+	&_saveround	(12,$out,-128,"%r8");		# KA<<<45
+	&_rotl128	("%rax","%rbx",15);		# 45+15=60
+	&_saveround	(13,$out,-128,"%rbx");		# KL<<<60
+	&_rotl128	("%r8","%r10",15);		# 45+15=60
+	&_saveround	(14,$out,-128,"%r8","%r10");	# KA<<<60
+	&_rotl128	("%rax","%rbx",17);		# 60+17=77
+	&_saveround	(16,$out,-128,"%rax","%rbx");	# KL<<<77
+	&_rotl128	("%rax","%rbx",17);		# 77+17=94
+	&_saveround	(18,$out,-128,"%rax","%rbx");	# KL<<<94
+	&_rotl128	("%r8","%r10",34);		# 60+34=94
+	&_saveround	(20,$out,-128,"%r8","%r10");	# KA<<<94
+	&_rotl128	("%rax","%rbx",17);		# 94+17=111
+	&_saveround	(22,$out,-128,"%rax","%rbx");	# KL<<<111
+	&_rotl128	("%r8","%r10",17);		# 94+17=111
+	&_saveround	(24,$out,-128,"%r8","%r10");	# KA<<<111
+$code.=<<___;
+	mov	\$3,%eax
+	jmp	.Ldone
+.align	16
+.L2nd256:
+___
+	&_saveround	(6,$out,@S);	# temp storage for KA!
+$code.=<<___;
+	xor	`4*8+0`($out),@S[1]	# KA^KR
+	xor	`4*8+4`($out),@S[0]
+	xor	`5*8+0`($out),@S[3]
+	xor	`5*8+4`($out),@S[2]
+___
+	&Camellia_Feistel($step++);
+	&Camellia_Feistel($step++);
+
+	&_loadround	(0,$out,"%rax","%rbx");	# KL
+	&_loadround	(4,$out,"%rcx","%rdx");	# KR
+	&_loadround	(6,$out,"%r14","%r15");	# KA
+$code.=<<___;
+	lea	128($out),$out		# size optimization
+	shl	\$32,%r8		# @S[0]||
+	shl	\$32,%r10		# @S[2]||
+	or	%r9,%r8			# ||@S[1]
+	or	%r11,%r10		# ||@S[3]
+___
+	&_saveround	(2,$out,-128,"%r8","%r10");	# KB<<<0
+	&_rotl128	("%rcx","%rdx",15);
+	&_saveround	(4,$out,-128,"%rcx","%rdx");	# KR<<<15
+	&_rotl128	("%r14","%r15",15);
+	&_saveround	(6,$out,-128,"%r14","%r15");	# KA<<<15
+	&_rotl128	("%rcx","%rdx",15);		# 15+15=30
+	&_saveround	(8,$out,-128,"%rcx","%rdx");	# KR<<<30
+	&_rotl128	("%r8","%r10",30);
+	&_saveround	(10,$out,-128,"%r8","%r10");	# KB<<<30
+	&_rotl128	("%rax","%rbx",45);
+	&_saveround	(12,$out,-128,"%rax","%rbx");	# KL<<<45
+	&_rotl128	("%r14","%r15",30);		# 15+30=45
+	&_saveround	(14,$out,-128,"%r14","%r15");	# KA<<<45
+	&_rotl128	("%rax","%rbx",15);		# 45+15=60
+	&_saveround	(16,$out,-128,"%rax","%rbx");	# KL<<<60
+	&_rotl128	("%rcx","%rdx",30);		# 30+30=60
+	&_saveround	(18,$out,-128,"%rcx","%rdx");	# KR<<<60
+	&_rotl128	("%r8","%r10",30);		# 30+30=60
+	&_saveround	(20,$out,-128,"%r8","%r10");	# KB<<<60
+	&_rotl128	("%rax","%rbx",17);		# 60+17=77
+	&_saveround	(22,$out,-128,"%rax","%rbx");	# KL<<<77
+	&_rotl128	("%r14","%r15",32);		# 45+32=77
+	&_saveround	(24,$out,-128,"%r14","%r15");	# KA<<<77
+	&_rotl128	("%rcx","%rdx",34);		# 60+34=94
+	&_saveround	(26,$out,-128,"%rcx","%rdx");	# KR<<<94
+	&_rotl128	("%r14","%r15",17);		# 77+17=94
+	&_saveround	(28,$out,-128,"%r14","%r15");	# KA<<<77
+	&_rotl128	("%rax","%rbx",34);		# 77+34=111
+	&_saveround	(30,$out,-128,"%rax","%rbx");	# KL<<<111
+	&_rotl128	("%r8","%r10",51);		# 60+51=111
+	&_saveround	(32,$out,-128,"%r8","%r10");	# KB<<<111
+$code.=<<___;
+	mov	\$4,%eax
+.Ldone:
+	mov	0(%rsp),%r15
+	mov	8(%rsp),%r14
+	mov	16(%rsp),%r13
+	mov	24(%rsp),%rbp
+	mov	32(%rsp),%rbx
+	lea	40(%rsp),%rsp
+.Lkey_epilogue:
+	ret
+.size	Camellia_Ekeygen,.-Camellia_Ekeygen
+___
+}
+
+@SBOX=(
+112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65,
+ 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189,
+134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26,
+166,225, 57,202,213, 71, 93, 61,217,  1, 90,214, 81, 86,108, 77,
+139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153,
+223, 76,203,194, 52,126,118,  5,109,183,169, 49,209, 23,  4,215,
+ 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34,
+254, 68,207,178,195,181,122,145, 36,  8,232,168, 96,252,105, 80,
+170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210,
+ 16,196,  0, 72,163,247,117,219,138,  3,230,218,  9, 63,221,148,
+135, 92,131,  2,205, 74,144, 51,115,103,246,243,157,127,191,226,
+ 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46,
+233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89,
+120,152,  6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250,
+114,  7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164,
+ 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158);
+
+sub S1110 { my $i=shift; $i=@SBOX[$i]; $i=$i<<24|$i<<16|$i<<8; sprintf("0x%08x",$i); }
+sub S4404 { my $i=shift; $i=($i<<1|$i>>7)&0xff; $i=@SBOX[$i]; $i=$i<<24|$i<<16|$i; sprintf("0x%08x",$i); }
+sub S0222 { my $i=shift; $i=@SBOX[$i]; $i=($i<<1|$i>>7)&0xff; $i=$i<<16|$i<<8|$i; sprintf("0x%08x",$i); }
+sub S3033 { my $i=shift; $i=@SBOX[$i]; $i=($i>>1|$i<<7)&0xff; $i=$i<<24|$i<<8|$i; sprintf("0x%08x",$i); }
+
+$code.=<<___;
+.align	64
+.LCamellia_SIGMA:
+.long	0x3bcc908b, 0xa09e667f, 0x4caa73b2, 0xb67ae858
+.long	0xe94f82be, 0xc6ef372f, 0xf1d36f1c, 0x54ff53a5
+.long	0xde682d1d, 0x10e527fa, 0xb3e6c1fd, 0xb05688c2
+.long	0,          0,          0,          0
+.LCamellia_SBOX:
+___
+# tables are interleaved, remember?
+sub data_word { $code.=".long\t".join(',',@_)."\n"; }
+for ($i=0;$i<256;$i++) { &data_word(&S1110($i),&S4404($i)); }
+for ($i=0;$i<256;$i++) { &data_word(&S0222($i),&S3033($i)); }
+
+# void Camellia_cbc_encrypt (const void char *inp, unsigned char *out,
+#			size_t length, const CAMELLIA_KEY *key,
+#			unsigned char *ivp,const int enc);
+{
+$_key="0(%rsp)";
+$_end="8(%rsp)";	# inp+len&~15
+$_res="16(%rsp)";	# len&15
+$ivec="24(%rsp)";
+$_ivp="40(%rsp)";
+$_rsp="48(%rsp)";
+
+$code.=<<___;
+.globl	Camellia_cbc_encrypt
+.type	Camellia_cbc_encrypt,\@function,6
+.align	16
+Camellia_cbc_encrypt:
+	cmp	\$0,%rdx
+	je	.Lcbc_abort
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+.Lcbc_prologue:
+
+	mov	%rsp,%rbp
+	sub	\$64,%rsp
+	and	\$-64,%rsp
+
+	# place stack frame just "above mod 1024" the key schedule,
+	# this ensures that cache associativity suffices
+	lea	-64-63(%rcx),%r10
+	sub	%rsp,%r10
+	neg	%r10
+	and	\$0x3C0,%r10
+	sub	%r10,%rsp
+	#add	\$8,%rsp		# 8 is reserved for callee's ra
+
+	mov	%rdi,$inp		# inp argument
+	mov	%rsi,$out		# out argument
+	mov	%r8,%rbx		# ivp argument
+	mov	%rcx,$key		# key argument
+	mov	272(%rcx),$keyend	# grandRounds
+
+	mov	%r8,$_ivp
+	mov	%rbp,$_rsp
+
+.Lcbc_body:
+	lea	.LCamellia_SBOX(%rip),$Tbl
+
+	mov	\$32,%ecx
+.align	4
+.Lcbc_prefetch_sbox:
+	mov	0($Tbl),%rax
+	mov	32($Tbl),%rsi
+	mov	64($Tbl),%rdi
+	mov	96($Tbl),%r11
+	lea	128($Tbl),$Tbl
+	loop	.Lcbc_prefetch_sbox
+	sub	\$4096,$Tbl
+	shl	\$6,$keyend
+	mov	%rdx,%rcx		# len argument
+	lea	($key,$keyend),$keyend
+
+	cmp	\$0,%r9d		# enc argument
+	je	.LCBC_DECRYPT
+
+	and	\$-16,%rdx
+	and	\$15,%rcx		# length residue
+	lea	($inp,%rdx),%rdx
+	mov	$key,$_key
+	mov	%rdx,$_end
+	mov	%rcx,$_res
+
+	cmp	$inp,%rdx
+	mov	0(%rbx),@S[0]		# load IV
+	mov	4(%rbx),@S[1]
+	mov	8(%rbx),@S[2]
+	mov	12(%rbx),@S[3]
+	je	.Lcbc_enc_tail
+	jmp	.Lcbc_eloop
+
+.align	16
+.Lcbc_eloop:
+	xor	0($inp),@S[0]
+	xor	4($inp),@S[1]
+	xor	8($inp),@S[2]
+	bswap	@S[0]
+	xor	12($inp),@S[3]
+	bswap	@S[1]
+	bswap	@S[2]
+	bswap	@S[3]
+
+	call	_x86_64_Camellia_encrypt
+
+	mov	$_key,$key		# "rewind" the key
+	bswap	@S[0]
+	mov	$_end,%rdx
+	bswap	@S[1]
+	mov	$_res,%rcx
+	bswap	@S[2]
+	mov	@S[0],0($out)
+	bswap	@S[3]
+	mov	@S[1],4($out)
+	mov	@S[2],8($out)
+	lea	16($inp),$inp
+	mov	@S[3],12($out)
+	cmp	%rdx,$inp
+	lea	16($out),$out
+	jne	.Lcbc_eloop
+
+	cmp	\$0,%rcx
+	jne	.Lcbc_enc_tail
+
+	mov	$_ivp,$out
+	mov	@S[0],0($out)		# write out IV residue
+	mov	@S[1],4($out)
+	mov	@S[2],8($out)
+	mov	@S[3],12($out)
+	jmp	.Lcbc_done
+
+.align	16
+.Lcbc_enc_tail:
+	xor	%rax,%rax
+	mov	%rax,0+$ivec
+	mov	%rax,8+$ivec
+	mov	%rax,$_res
+
+.Lcbc_enc_pushf:
+	pushfq
+	cld
+	mov	$inp,%rsi
+	lea	8+$ivec,%rdi
+	.long	0x9066A4F3		# rep movsb
+	popfq
+.Lcbc_enc_popf:
+
+	lea	$ivec,$inp
+	lea	16+$ivec,%rax
+	mov	%rax,$_end
+	jmp	.Lcbc_eloop		# one more time
+
+.align	16
+.LCBC_DECRYPT:
+	xchg	$key,$keyend
+	add	\$15,%rdx
+	and	\$15,%rcx		# length residue
+	and	\$-16,%rdx
+	mov	$key,$_key
+	lea	($inp,%rdx),%rdx
+	mov	%rdx,$_end
+	mov	%rcx,$_res
+
+	mov	(%rbx),%rax		# load IV
+	mov	8(%rbx),%rbx
+	jmp	.Lcbc_dloop
+.align	16
+.Lcbc_dloop:
+	mov	0($inp),@S[0]
+	mov	4($inp),@S[1]
+	mov	8($inp),@S[2]
+	bswap	@S[0]
+	mov	12($inp),@S[3]
+	bswap	@S[1]
+	mov	%rax,0+$ivec		# save IV to temporary storage
+	bswap	@S[2]
+	mov	%rbx,8+$ivec
+	bswap	@S[3]
+
+	call	_x86_64_Camellia_decrypt
+
+	mov	$_key,$key		# "rewind" the key
+	mov	$_end,%rdx
+	mov	$_res,%rcx
+
+	bswap	@S[0]
+	mov	($inp),%rax		# load IV for next iteration
+	bswap	@S[1]
+	mov	8($inp),%rbx
+	bswap	@S[2]
+	xor	0+$ivec,@S[0]
+	bswap	@S[3]
+	xor	4+$ivec,@S[1]
+	xor	8+$ivec,@S[2]
+	lea	16($inp),$inp
+	xor	12+$ivec,@S[3]
+	cmp	%rdx,$inp
+	je	.Lcbc_ddone
+
+	mov	@S[0],0($out)
+	mov	@S[1],4($out)
+	mov	@S[2],8($out)
+	mov	@S[3],12($out)
+
+	lea	16($out),$out
+	jmp	.Lcbc_dloop
+
+.align	16
+.Lcbc_ddone:
+	mov	$_ivp,%rdx
+	cmp	\$0,%rcx
+	jne	.Lcbc_dec_tail
+
+	mov	@S[0],0($out)
+	mov	@S[1],4($out)
+	mov	@S[2],8($out)
+	mov	@S[3],12($out)
+
+	mov	%rax,(%rdx)		# write out IV residue
+	mov	%rbx,8(%rdx)
+	jmp	.Lcbc_done
+.align	16
+.Lcbc_dec_tail:
+	mov	@S[0],0+$ivec
+	mov	@S[1],4+$ivec
+	mov	@S[2],8+$ivec
+	mov	@S[3],12+$ivec
+
+.Lcbc_dec_pushf:
+	pushfq
+	cld
+	lea	8+$ivec,%rsi
+	lea	($out),%rdi
+	.long	0x9066A4F3		# rep movsb
+	popfq
+.Lcbc_dec_popf:
+
+	mov	%rax,(%rdx)		# write out IV residue
+	mov	%rbx,8(%rdx)
+	jmp	.Lcbc_done
+
+.align	16
+.Lcbc_done:
+	mov	$_rsp,%rcx
+	mov	0(%rcx),%r15
+	mov	8(%rcx),%r14
+	mov	16(%rcx),%r13
+	mov	24(%rcx),%r12
+	mov	32(%rcx),%rbp
+	mov	40(%rcx),%rbx
+	lea	48(%rcx),%rsp
+.Lcbc_abort:
+	ret
+.size	Camellia_cbc_encrypt,.-Camellia_cbc_encrypt
+
+.asciz	"Camellia for x86_64 by <appro@openssl.org>"
+___
+}
+
+# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
+#		CONTEXT *context,DISPATCHER_CONTEXT *disp)
+if ($win64) {
+$rec="%rcx";
+$frame="%rdx";
+$context="%r8";
+$disp="%r9";
+
+$code.=<<___;
+.extern	__imp_RtlVirtualUnwind
+.type	common_se_handler,\@abi-omnipotent
+.align	16
+common_se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	lea	-64(%rsp),%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	mov	8($disp),%rsi		# disp->ImageBase
+	mov	56($disp),%r11		# disp->HandlerData
+
+	mov	0(%r11),%r10d		# HandlerData[0]
+	lea	(%rsi,%r10),%r10	# prologue label
+	cmp	%r10,%rbx		# context->Rip<prologue label
+	jb	.Lin_prologue
+
+	mov	152($context),%rax	# pull context->Rsp
+
+	mov	4(%r11),%r10d		# HandlerData[1]
+	lea	(%rsi,%r10),%r10	# epilogue label
+	cmp	%r10,%rbx		# context->Rip>=epilogue label
+	jae	.Lin_prologue
+
+	lea	40(%rax),%rax
+	mov	-8(%rax),%rbx
+	mov	-16(%rax),%rbp
+	mov	-24(%rax),%r13
+	mov	-32(%rax),%r14
+	mov	-40(%rax),%r15
+	mov	%rbx,144($context)	# restore context->Rbx
+	mov	%rbp,160($context)	# restore context->Rbp
+	mov	%r13,224($context)	# restore context->R13
+	mov	%r14,232($context)	# restore context->R14
+	mov	%r15,240($context)	# restore context->R15
+
+.Lin_prologue:
+	mov	8(%rax),%rdi
+	mov	16(%rax),%rsi
+	mov	%rax,152($context)	# restore context->Rsp
+	mov	%rsi,168($context)	# restore context->Rsi
+	mov	%rdi,176($context)	# restore context->Rdi
+
+	jmp	.Lcommon_seh_exit
+.size	common_se_handler,.-common_se_handler
+
+.type	cbc_se_handler,\@abi-omnipotent
+.align	16
+cbc_se_handler:
+	push	%rsi
+	push	%rdi
+	push	%rbx
+	push	%rbp
+	push	%r12
+	push	%r13
+	push	%r14
+	push	%r15
+	pushfq
+	lea	-64(%rsp),%rsp
+
+	mov	120($context),%rax	# pull context->Rax
+	mov	248($context),%rbx	# pull context->Rip
+
+	lea	.Lcbc_prologue(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lcbc_prologue
+	jb	.Lin_cbc_prologue
+
+	lea	.Lcbc_body(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lcbc_body
+	jb	.Lin_cbc_frame_setup
+
+	mov	152($context),%rax	# pull context->Rsp
+
+	lea	.Lcbc_abort(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip>=.Lcbc_abort
+	jae	.Lin_cbc_prologue
+
+	# handle pushf/popf in Camellia_cbc_encrypt
+	lea	.Lcbc_enc_pushf(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<=.Lcbc_enc_pushf
+	jbe	.Lin_cbc_no_flag
+	lea	8(%rax),%rax
+	lea	.Lcbc_enc_popf(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lcbc_enc_popf
+	jb	.Lin_cbc_no_flag
+	lea	-8(%rax),%rax
+	lea	.Lcbc_dec_pushf(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<=.Lcbc_dec_pushf
+	jbe	.Lin_cbc_no_flag
+	lea	8(%rax),%rax
+	lea	.Lcbc_dec_popf(%rip),%r10
+	cmp	%r10,%rbx		# context->Rip<.Lcbc_dec_popf
+	jb	.Lin_cbc_no_flag
+	lea	-8(%rax),%rax
+
+.Lin_cbc_no_flag:
+	mov	48(%rax),%rax		# $_rsp
+	lea	48(%rax),%rax
+
+.Lin_cbc_frame_setup:
+	mov	-8(%rax),%rbx
+	mov	-16(%rax),%rbp
+	mov	-24(%rax),%r12
+	mov	-32(%rax),%r13
+	mov	-40(%rax),%r14
+	mov	-48(%rax),%r15
+	mov	%rbx,144($context)	# restore context->Rbx
+	mov	%rbp,160($context)	# restore context->Rbp
+	mov	%r12,216($context)	# restore context->R12
+	mov	%r13,224($context)	# restore context->R13
+	mov	%r14,232($context)	# restore context->R14
+	mov	%r15,240($context)	# restore context->R15
+
+.Lin_cbc_prologue:
+	mov	8(%rax),%rdi
+	mov	16(%rax),%rsi
+	mov	%rax,152($context)	# restore context->Rsp
+	mov	%rsi,168($context)	# restore context->Rsi
+	mov	%rdi,176($context)	# restore context->Rdi
+
+.align	4
+.Lcommon_seh_exit:
+
+	mov	40($disp),%rdi		# disp->ContextRecord
+	mov	$context,%rsi		# context
+	mov	\$`1232/8`,%ecx		# sizeof(CONTEXT)
+	.long	0xa548f3fc		# cld; rep movsq
+
+	mov	$disp,%rsi
+	xor	%rcx,%rcx		# arg1, UNW_FLAG_NHANDLER
+	mov	8(%rsi),%rdx		# arg2, disp->ImageBase
+	mov	0(%rsi),%r8		# arg3, disp->ControlPc
+	mov	16(%rsi),%r9		# arg4, disp->FunctionEntry
+	mov	40(%rsi),%r10		# disp->ContextRecord
+	lea	56(%rsi),%r11		# &disp->HandlerData
+	lea	24(%rsi),%r12		# &disp->EstablisherFrame
+	mov	%r10,32(%rsp)		# arg5
+	mov	%r11,40(%rsp)		# arg6
+	mov	%r12,48(%rsp)		# arg7
+	mov	%rcx,56(%rsp)		# arg8, (NULL)
+	call	*__imp_RtlVirtualUnwind(%rip)
+
+	mov	\$1,%eax		# ExceptionContinueSearch
+	lea	64(%rsp),%rsp
+	popfq
+	pop	%r15
+	pop	%r14
+	pop	%r13
+	pop	%r12
+	pop	%rbp
+	pop	%rbx
+	pop	%rdi
+	pop	%rsi
+	ret
+.size	cbc_se_handler,.-cbc_se_handler
+
+.section	.pdata
+.align	4
+	.rva	.LSEH_begin_Camellia_EncryptBlock_Rounds
+	.rva	.LSEH_end_Camellia_EncryptBlock_Rounds
+	.rva	.LSEH_info_Camellia_EncryptBlock_Rounds
+
+	.rva	.LSEH_begin_Camellia_DecryptBlock_Rounds
+	.rva	.LSEH_end_Camellia_DecryptBlock_Rounds
+	.rva	.LSEH_info_Camellia_DecryptBlock_Rounds
+
+	.rva	.LSEH_begin_Camellia_Ekeygen
+	.rva	.LSEH_end_Camellia_Ekeygen
+	.rva	.LSEH_info_Camellia_Ekeygen
+
+	.rva	.LSEH_begin_Camellia_cbc_encrypt
+	.rva	.LSEH_end_Camellia_cbc_encrypt
+	.rva	.LSEH_info_Camellia_cbc_encrypt
+
+.section	.xdata
+.align	8
+.LSEH_info_Camellia_EncryptBlock_Rounds:
+	.byte	9,0,0,0
+	.rva	common_se_handler
+	.rva	.Lenc_prologue,.Lenc_epilogue	# HandlerData[]
+.LSEH_info_Camellia_DecryptBlock_Rounds:
+	.byte	9,0,0,0
+	.rva	common_se_handler
+	.rva	.Ldec_prologue,.Ldec_epilogue	# HandlerData[]
+.LSEH_info_Camellia_Ekeygen:
+	.byte	9,0,0,0
+	.rva	common_se_handler
+	.rva	.Lkey_prologue,.Lkey_epilogue	# HandlerData[]
+.LSEH_info_Camellia_cbc_encrypt:
+	.byte	9,0,0,0
+	.rva	cbc_se_handler
+___
+}
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/crypto/camellia/camellia.h b/crypto/camellia/camellia.h
index 3c8a359..b8a8b6e 100644
--- a/crypto/camellia/camellia.h
+++ b/crypto/camellia/camellia.h
@@ -87,6 +87,11 @@
 
 typedef struct camellia_key_st CAMELLIA_KEY;
 
+#ifdef OPENSSL_FIPS
+int private_Camellia_set_key(const unsigned char *userKey, const int bits,
+	CAMELLIA_KEY *key);
+#endif
+
 int Camellia_set_key(const unsigned char *userKey, const int bits,
 	CAMELLIA_KEY *key);
 
diff --git a/crypto/camellia/cmll_misc.c b/crypto/camellia/cmll_misc.c
index f1047b5..2cd7aba 100644
--- a/crypto/camellia/cmll_misc.c
+++ b/crypto/camellia/cmll_misc.c
@@ -52,11 +52,24 @@
 #include <openssl/opensslv.h>
 #include <openssl/camellia.h>
 #include "cmll_locl.h"
+#include <openssl/crypto.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
 
 const char CAMELLIA_version[]="CAMELLIA" OPENSSL_VERSION_PTEXT;
 
 int Camellia_set_key(const unsigned char *userKey, const int bits,
 	CAMELLIA_KEY *key)
+#ifdef OPENSSL_FIPS
+	{
+	if (FIPS_mode())
+		FIPS_BAD_ABORT(CAMELLIA)
+	return private_Camellia_set_key(userKey, bits, key);
+	}
+int private_Camellia_set_key(const unsigned char *userKey, const int bits,
+	CAMELLIA_KEY *key)
+#endif
 	{
 	if (!userKey || !key)
 		{
diff --git a/crypto/comp/Makefile b/crypto/comp/Makefile
index efda832..5d364b8 100644
--- a/crypto/comp/Makefile
+++ b/crypto/comp/Makefile
@@ -36,7 +36,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
diff --git a/crypto/comp/c_zlib.c b/crypto/comp/c_zlib.c
index 0f34597..eccfd09 100644
--- a/crypto/comp/c_zlib.c
+++ b/crypto/comp/c_zlib.c
@@ -727,6 +727,7 @@
 	case BIO_CTRL_RESET:
 		ctx->ocount = 0;
 		ctx->odone = 0;
+		ret = 1;
 		break;
 
 	case BIO_CTRL_FLUSH:
@@ -771,7 +772,7 @@
 				}
 			ctx->obufsize = obs;
 			}
-
+		ret = 1;
 		break;
 
 	case BIO_C_DO_STATE_MACHINE:
@@ -783,7 +784,6 @@
 	default:
 		ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
 		break;
-
 		}
 
 	return ret;
diff --git a/crypto/conf/Makefile b/crypto/conf/Makefile
index 78bb324..ccd0721 100644
--- a/crypto/conf/Makefile
+++ b/crypto/conf/Makefile
@@ -36,7 +36,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -114,8 +114,8 @@
 conf_mall.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 conf_mall.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
 conf_mall.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-conf_mall.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-conf_mall.o: ../../include/openssl/objects.h
+conf_mall.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+conf_mall.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 conf_mall.o: ../../include/openssl/opensslconf.h
 conf_mall.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 conf_mall.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
@@ -128,9 +128,9 @@
 conf_mod.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
 conf_mod.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 conf_mod.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-conf_mod.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-conf_mod.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-conf_mod.o: ../../include/openssl/opensslconf.h
+conf_mod.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+conf_mod.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+conf_mod.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 conf_mod.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 conf_mod.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 conf_mod.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -143,8 +143,9 @@
 conf_sap.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 conf_sap.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
 conf_sap.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-conf_sap.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-conf_sap.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+conf_sap.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+conf_sap.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+conf_sap.o: ../../include/openssl/opensslconf.h
 conf_sap.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 conf_sap.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 conf_sap.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
diff --git a/crypto/conf/conf_mall.c b/crypto/conf/conf_mall.c
index 4ba40cf..1cc1fd5 100644
--- a/crypto/conf/conf_mall.c
+++ b/crypto/conf/conf_mall.c
@@ -1,5 +1,5 @@
 /* conf_mall.c */
-/* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
  * project 2001.
  */
 /* ====================================================================
@@ -63,6 +63,7 @@
 #include <openssl/dso.h>
 #include <openssl/x509.h>
 #include <openssl/asn1.h>
+#include <openssl/evp.h>
 #ifndef OPENSSL_NO_ENGINE
 #include <openssl/engine.h>
 #endif
@@ -76,5 +77,6 @@
 #ifndef OPENSSL_NO_ENGINE
 	ENGINE_add_conf_module();
 #endif
+	EVP_add_alg_module();
 	}
 
diff --git a/crypto/conf/conf_mod.c b/crypto/conf/conf_mod.c
index 628e833..ee9c677 100644
--- a/crypto/conf/conf_mod.c
+++ b/crypto/conf/conf_mod.c
@@ -1,5 +1,5 @@
 /* conf_mod.c */
-/* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
  * project 2001.
  */
 /* ====================================================================
diff --git a/crypto/conf/conf_sap.c b/crypto/conf/conf_sap.c
index 9c53bac..760dc26 100644
--- a/crypto/conf/conf_sap.c
+++ b/crypto/conf/conf_sap.c
@@ -1,5 +1,5 @@
 /* conf_sap.c */
-/* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
  * project 2001.
  */
 /* ====================================================================
diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c
index 8c68623..8f9e88e 100644
--- a/crypto/cryptlib.c
+++ b/crypto/cryptlib.c
@@ -121,275 +121,17 @@
 static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */
 #endif
 
-DECLARE_STACK_OF(CRYPTO_dynlock)
-IMPLEMENT_STACK_OF(CRYPTO_dynlock)
-
-/* real #defines in crypto.h, keep these upto date */
-static const char* const lock_names[CRYPTO_NUM_LOCKS] =
-	{
-	"<<ERROR>>",
-	"err",
-	"ex_data",
-	"x509",
-	"x509_info",
-	"x509_pkey",
-	"x509_crl",
-	"x509_req",
-	"dsa",
-	"rsa",
-	"evp_pkey",
-	"x509_store",
-	"ssl_ctx",
-	"ssl_cert",
-	"ssl_session",
-	"ssl_sess_cert",
-	"ssl",
-	"ssl_method",
-	"rand",
-	"rand2",
-	"debug_malloc",
-	"BIO",
-	"gethostbyname",
-	"getservbyname",
-	"readdir",
-	"RSA_blinding",
-	"dh",
-	"debug_malloc2",
-	"dso",
-	"dynlock",
-	"engine",
-	"ui",
-	"ecdsa",
-	"ec",
-	"ecdh",
-	"bn",
-	"ec_pre_comp",
-	"store",
-	"comp",
-#if CRYPTO_NUM_LOCKS != 39
-# error "Inconsistency between crypto.h and cryptlib.c"
-#endif
-	};
-
-/* This is for applications to allocate new type names in the non-dynamic
-   array of lock names.  These are numbered with positive numbers.  */
-static STACK *app_locks=NULL;
-
-/* For applications that want a more dynamic way of handling threads, the
-   following stack is used.  These are externally numbered with negative
-   numbers.  */
-static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL;
-
-
 static void (MS_FAR *locking_callback)(int mode,int type,
 	const char *file,int line)=NULL;
 static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
 	int type,const char *file,int line)=NULL;
 static unsigned long (MS_FAR *id_callback)(void)=NULL;
-static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
-	(const char *file,int line)=NULL;
-static void (MS_FAR *dynlock_lock_callback)(int mode,
-	struct CRYPTO_dynlock_value *l, const char *file,int line)=NULL;
-static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l,
-	const char *file,int line)=NULL;
-
-int CRYPTO_get_new_lockid(char *name)
-	{
-	char *str;
-	int i;
-
-#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
-	/* A hack to make Visual C++ 5.0 work correctly when linking as
-	 * a DLL using /MT. Without this, the application cannot use
-	 * and floating point printf's.
-	 * It also seems to be needed for Visual C 1.5 (win16) */
-	SSLeay_MSVC5_hack=(double)name[0]*(double)name[1];
-#endif
-
-	if ((app_locks == NULL) && ((app_locks=sk_new_null()) == NULL))
-		{
-		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
-		return(0);
-		}
-	if ((str=BUF_strdup(name)) == NULL)
-		{
-		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
-		return(0);
-		}
-	i=sk_push(app_locks,str);
-	if (!i)
-		OPENSSL_free(str);
-	else
-		i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */
-	return(i);
-	}
 
 int CRYPTO_num_locks(void)
 	{
 	return CRYPTO_NUM_LOCKS;
 	}
 
-int CRYPTO_get_new_dynlockid(void)
-	{
-	int i = 0;
-	CRYPTO_dynlock *pointer = NULL;
-
-	if (dynlock_create_callback == NULL)
-		{
-		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
-		return(0);
-		}
-	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
-	if ((dyn_locks == NULL)
-		&& ((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL))
-		{
-		CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
-		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
-		return(0);
-		}
-	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
-
-	pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock));
-	if (pointer == NULL)
-		{
-		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
-		return(0);
-		}
-	pointer->references = 1;
-	pointer->data = dynlock_create_callback(__FILE__,__LINE__);
-	if (pointer->data == NULL)
-		{
-		OPENSSL_free(pointer);
-		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
-		return(0);
-		}
-
-	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
-	/* First, try to find an existing empty slot */
-	i=sk_CRYPTO_dynlock_find(dyn_locks,NULL);
-	/* If there was none, push, thereby creating a new one */
-	if (i == -1)
-		/* Since sk_push() returns the number of items on the
-		   stack, not the location of the pushed item, we need
-		   to transform the returned number into a position,
-		   by decreasing it.  */
-		i=sk_CRYPTO_dynlock_push(dyn_locks,pointer) - 1;
-	else
-		/* If we found a place with a NULL pointer, put our pointer
-		   in it.  */
-		(void)sk_CRYPTO_dynlock_set(dyn_locks,i,pointer);
-	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
-
-	if (i == -1)
-		{
-		dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
-		OPENSSL_free(pointer);
-		}
-	else
-		i += 1; /* to avoid 0 */
-	return -i;
-	}
-
-void CRYPTO_destroy_dynlockid(int i)
-	{
-	CRYPTO_dynlock *pointer = NULL;
-	if (i)
-		i = -i-1;
-	if (dynlock_destroy_callback == NULL)
-		return;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
-
-	if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks))
-		{
-		CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
-		return;
-		}
-	pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
-	if (pointer != NULL)
-		{
-		--pointer->references;
-#ifdef REF_CHECK
-		if (pointer->references < 0)
-			{
-			fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference count\n");
-			abort();
-			}
-		else
-#endif
-			if (pointer->references <= 0)
-				{
-				(void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
-				}
-			else
-				pointer = NULL;
-		}
-	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
-
-	if (pointer)
-		{
-		dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
-		OPENSSL_free(pointer);
-		}
-	}
-
-struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i)
-	{
-	CRYPTO_dynlock *pointer = NULL;
-	if (i)
-		i = -i-1;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
-
-	if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
-		pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
-	if (pointer)
-		pointer->references++;
-
-	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
-
-	if (pointer)
-		return pointer->data;
-	return NULL;
-	}
-
-struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))
-	(const char *file,int line)
-	{
-	return(dynlock_create_callback);
-	}
-
-void (*CRYPTO_get_dynlock_lock_callback(void))(int mode,
-	struct CRYPTO_dynlock_value *l, const char *file,int line)
-	{
-	return(dynlock_lock_callback);
-	}
-
-void (*CRYPTO_get_dynlock_destroy_callback(void))
-	(struct CRYPTO_dynlock_value *l, const char *file,int line)
-	{
-	return(dynlock_destroy_callback);
-	}
-
-void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
-	(const char *file, int line))
-	{
-	dynlock_create_callback=func;
-	}
-
-void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode,
-	struct CRYPTO_dynlock_value *l, const char *file, int line))
-	{
-	dynlock_lock_callback=func;
-	}
-
-void CRYPTO_set_dynlock_destroy_callback(void (*func)
-	(struct CRYPTO_dynlock_value *l, const char *file, int line))
-	{
-	dynlock_destroy_callback=func;
-	}
-
-
 void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
 		int line)
 	{
@@ -445,6 +187,14 @@
 	return(ret);
 	}
 
+static void (*do_dynlock_cb)(int mode, int type, const char *file, int line);
+
+void int_CRYPTO_set_do_dynlock_callback(
+	void (*dyn_cb)(int mode, int type, const char *file, int line))
+	{
+	do_dynlock_cb = dyn_cb;
+	}
+
 void CRYPTO_lock(int mode, int type, const char *file, int line)
 	{
 #ifdef LOCK_DEBUG
@@ -472,17 +222,8 @@
 #endif
 	if (type < 0)
 		{
-		if (dynlock_lock_callback != NULL)
-			{
-			struct CRYPTO_dynlock_value *pointer
-				= CRYPTO_get_dynlock_value(type);
-
-			OPENSSL_assert(pointer != NULL);
-
-			dynlock_lock_callback(mode, pointer, file, line);
-
-			CRYPTO_destroy_dynlockid(type);
-			}
+		if (do_dynlock_cb)
+			do_dynlock_cb(mode, type, file, line);
 		}
 	else
 		if (locking_callback != NULL)
@@ -527,21 +268,9 @@
 	return(ret);
 	}
 
-const char *CRYPTO_get_lock_name(int type)
-	{
-	if (type < 0)
-		return("dynamic");
-	else if (type < CRYPTO_NUM_LOCKS)
-		return(lock_names[type]);
-	else if (type-CRYPTO_NUM_LOCKS > sk_num(app_locks))
-		return("ERROR");
-	else
-		return(sk_value(app_locks,type-CRYPTO_NUM_LOCKS));
-	}
-
 #if	defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
 	defined(__INTEL__) || \
-	defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64)
+	defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
 
 unsigned long  OPENSSL_ia32cap_P=0;
 unsigned long *OPENSSL_ia32cap_loc(void) { return &OPENSSL_ia32cap_P; }
@@ -577,6 +306,62 @@
 #endif
 
 #if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL)
+
+#ifdef OPENSSL_FIPS
+
+#include <tlhelp32.h>
+#if defined(__GNUC__) && __GNUC__>=2
+static int DllInit(void) __attribute__((constructor));
+#elif defined(_MSC_VER)
+static int DllInit(void);
+# ifdef _WIN64
+# pragma section(".CRT$XCU",read)
+  __declspec(allocate(".CRT$XCU"))
+# else
+# pragma data_seg(".CRT$XCU")
+# endif
+  static int (*p)(void) = DllInit;
+# pragma data_seg()
+#endif
+
+static int DllInit(void)
+{
+#if defined(_WIN32_WINNT)
+	union	{ int(*f)(void); BYTE *p; } t = { DllInit };
+        HANDLE	hModuleSnap = INVALID_HANDLE_VALUE;
+	IMAGE_DOS_HEADER *dos_header;
+	IMAGE_NT_HEADERS *nt_headers;
+	MODULEENTRY32 me32 = {sizeof(me32)};
+
+	hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0);
+	if (hModuleSnap != INVALID_HANDLE_VALUE &&
+	    Module32First(hModuleSnap,&me32)) do
+		{
+		if (t.p >= me32.modBaseAddr &&
+		    t.p <  me32.modBaseAddr+me32.modBaseSize)
+			{
+			dos_header=(IMAGE_DOS_HEADER *)me32.modBaseAddr;
+			if (dos_header->e_magic==IMAGE_DOS_SIGNATURE)
+				{
+				nt_headers=(IMAGE_NT_HEADERS *)
+					((BYTE *)dos_header+dos_header->e_lfanew);
+				if (nt_headers->Signature==IMAGE_NT_SIGNATURE &&
+				    me32.modBaseAddr!=(BYTE*)nt_headers->OptionalHeader.ImageBase)
+					OPENSSL_NONPIC_relocated=1;
+				}
+			break;
+			}
+		} while (Module32Next(hModuleSnap,&me32));
+
+	if (hModuleSnap != INVALID_HANDLE_VALUE)
+		CloseHandle(hModuleSnap);
+#endif
+	OPENSSL_cpuid_setup();
+	return 0;
+}
+
+#else
+
 #ifdef __CYGWIN__
 /* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
 #include <windows.h>
@@ -620,6 +405,8 @@
 	}
 #endif
 
+#endif
+
 #if defined(_WIN32) && !defined(__CYGWIN__)
 #include <tchar.h>
 
diff --git a/crypto/cryptlib.h b/crypto/cryptlib.h
index 5ceaa96..fc249c5 100644
--- a/crypto/cryptlib.h
+++ b/crypto/cryptlib.h
@@ -103,7 +103,6 @@
 void OPENSSL_showfatal(const char *,...);
 void *OPENSSL_stderr(void);
 extern int OPENSSL_NONPIC_relocated;
-int OPENSSL_isservice(void);
 
 #ifdef  __cplusplus
 }
diff --git a/crypto/crypto-lib.com b/crypto/crypto-lib.com
index 8898f30..e72af90 100644
--- a/crypto/crypto-lib.com
+++ b/crypto/crypto-lib.com
@@ -83,7 +83,7 @@
 		  "BUFFER,BIO,STACK,LHASH,RAND,ERR,"+ -
 		  "EVP,EVP_2,ASN1,ASN1_2,PEM,X509,X509V3,"+ -
 		  "CONF,TXT_DB,PKCS7,PKCS12,COMP,OCSP,UI,KRB5,"+ -
-		  "STORE,CMS,PQUEUE"
+		  "STORE,CMS,PQUEUE,JPAKE"
 $!
 $! Check To Make Sure We Have Valid Command Line Parameters.
 $!
@@ -161,7 +161,7 @@
 $ APPS_DES = "DES/DES,CBC3_ENC"
 $ APPS_PKCS7 = "ENC/ENC;DEC/DEC;SIGN/SIGN;VERIFY/VERIFY,EXAMPLE"
 $
-$ LIB_ = "cryptlib,mem,mem_clr,mem_dbg,cversion,ex_data,tmdiff,cpt_err,ebcdic,uid,o_time,o_str,o_dir"
+$ LIB_ = "cryptlib,dyn_lck,mem,mem_clr,mem_dbg,cversion,ex_data,tmdiff,cpt_err,ebcdic,uid,o_time,o_str,o_dir,o_init,fips_err"
 $ LIB_MD2 = "md2_dgst,md2_one"
 $ LIB_MD4 = "md4_dgst,md4_one"
 $ LIB_MD5 = "md5_dgst,md5_one"
@@ -169,7 +169,7 @@
 $ LIB_MDC2 = "mdc2dgst,mdc2_one"
 $ LIB_HMAC = "hmac"
 $ LIB_RIPEMD = "rmd_dgst,rmd_one"
-$ LIB_DES = "set_key,ecb_enc,cbc_enc,"+ -
+$ LIB_DES = "des_lib,set_key,ecb_enc,cbc_enc,"+ -
 	"ecb3_enc,cfb64enc,cfb64ede,cfb_enc,ofb64ede,"+ -
 	"enc_read,enc_writ,ofb64enc,"+ -
 	"ofb_enc,str2key,pcbc_enc,qud_cksm,rand_key,"+ -
@@ -191,15 +191,15 @@
 	"bn_print,bn_rand,bn_shift,bn_word,bn_blind,"+ -
 	"bn_kron,bn_sqrt,bn_gcd,bn_prime,bn_err,bn_sqr,"+LIB_BN_ASM+","+ -
 	"bn_recp,bn_mont,bn_mpi,bn_exp2,bn_gf2m,bn_nist,"+ -
-	"bn_depr,bn_const"
+	"bn_depr,bn_x931p,bn_const,bn_opt"
 $ LIB_EC = "ec_lib,ecp_smpl,ecp_mont,ecp_nist,ec_cvt,ec_mult,"+ -
 	"ec_err,ec_curve,ec_check,ec_print,ec_asn1,ec_key,"+ -
 	"ec2_smpl,ec2_mult"
 $ LIB_RSA = "rsa_eay,rsa_gen,rsa_lib,rsa_sign,rsa_saos,rsa_err,"+ -
 	"rsa_pk1,rsa_ssl,rsa_none,rsa_oaep,rsa_chk,rsa_null,"+ -
-	"rsa_pss,rsa_x931,rsa_asn1,rsa_depr"
+	"rsa_pss,rsa_x931,rsa_x931g,rsa_asn1,rsa_depr,rsa_eng"
 $ LIB_DSA = "dsa_gen,dsa_key,dsa_lib,dsa_asn1,dsa_vrf,dsa_sign,"+ -
-	"dsa_err,dsa_ossl,dsa_depr"
+	"dsa_err,dsa_ossl,dsa_depr,dsa_utl"
 $ LIB_ECDSA = "ecs_lib,ecs_asn1,ecs_ossl,ecs_sign,ecs_vrf,ecs_err"
 $ LIB_DH = "dh_asn1,dh_gen,dh_key,dh_lib,dh_check,dh_err,dh_depr"
 $ LIB_ECDH = "ech_lib,ech_ossl,ech_key,ech_err"
@@ -212,7 +212,7 @@
 	"eng_openssl,eng_dyn,eng_cnf,eng_cryptodev,eng_padlock"
 $ LIB_AES = "aes_core,aes_misc,aes_ecb,aes_cbc,aes_cfb,aes_ofb,"+ -
 	"aes_ctr,aes_ige,aes_wrap"
-$ LIB_BUFFER = "buffer,buf_err"
+$ LIB_BUFFER = "buffer,buf_str,buf_err"
 $ LIB_BIO = "bio_lib,bio_cb,bio_err,"+ -
 	"bss_mem,bss_null,bss_fd,"+ -
 	"bss_file,bss_sock,bss_conn,"+ -
@@ -224,18 +224,19 @@
 $ LIB_LHASH = "lhash,lh_stats"
 $ LIB_RAND = "md_rand,randfile,rand_lib,rand_err,rand_egd,"+ -
 	"rand_vms"
-$ LIB_ERR = "err,err_all,err_prn"
+$ LIB_ERR = "err,err_def,err_all,err_prn,err_str,err_bio"
 $ LIB_OBJECTS = "o_names,obj_dat,obj_lib,obj_err"
-$ LIB_EVP = "encode,digest,evp_enc,evp_key,evp_acnf,"+ -
-	"e_des,e_bf,e_idea,e_des3,e_camellia,e_seed,"+ -
-	"e_rc4,e_aes,names,"+ -
-	"e_xcbc_d,e_rc2,e_cast,e_rc5"
+$ LIB_EVP = "encode,digest,dig_eng,evp_enc,evp_key,evp_acnf,evp_cnf,"+ -
+	"e_des,e_bf,e_idea,e_des3,e_camellia,"+ -
+	"e_rc4,e_aes,names,e_seed,"+ -
+	"e_xcbc_d,e_rc2,e_cast,e_rc5,enc_min"
 $ LIB_EVP_2 = "m_null,m_md2,m_md4,m_md5,m_sha,m_sha1," + -
 	"m_dss,m_dss1,m_mdc2,m_ripemd,m_ecdsa,"+ -
 	"p_open,p_seal,p_sign,p_verify,p_lib,p_enc,p_dec,"+ -
 	"bio_md,bio_b64,bio_enc,evp_err,e_null,"+ -
 	"c_all,c_allc,c_alld,evp_lib,bio_ok,"+-
 	"evp_pkey,evp_pbe,p5_crpt,p5_crpt2"
+$ LIB_EVP_3 = "e_old"
 $ LIB_ASN1 = "a_object,a_bitstr,a_utctm,a_gentm,a_time,a_int,a_octet,"+ -
 	"a_print,a_type,a_set,a_dup,a_d2i_fp,a_i2d_fp,"+ -
 	"a_enum,a_utf8,a_sign,a_digest,a_verify,a_mbstr,a_strex,"+ -
@@ -280,6 +281,7 @@
 $ LIB_CMS = "cms_lib,cms_asn1,cms_att,cms_io,cms_smime,cms_err,"+ -
 	"cms_sd,cms_dd,cms_cd,cms_env,cms_enc,cms_ess"
 $ LIB_PQUEUE = "pqueue"
+$ LIB_JPAKE = "jpake,jpake_err"
 $!
 $! Setup exceptional compilations
 $!
diff --git a/crypto/crypto.h b/crypto/crypto.h
index d2b5ffe..0e4fb07 100644
--- a/crypto/crypto.h
+++ b/crypto/crypto.h
@@ -219,7 +219,13 @@
 #define CRYPTO_LOCK_EC_PRE_COMP		36
 #define CRYPTO_LOCK_STORE		37
 #define CRYPTO_LOCK_COMP		38
+#ifndef OPENSSL_FIPS
 #define CRYPTO_NUM_LOCKS		39
+#else
+#define CRYPTO_LOCK_FIPS		39
+#define CRYPTO_LOCK_FIPS2		40
+#define CRYPTO_NUM_LOCKS		41
+#endif
 
 #define CRYPTO_LOCK		1
 #define CRYPTO_UNLOCK		2
@@ -341,14 +347,7 @@
 
 /* Set standard debugging functions (not done by default
  * unless CRYPTO_MDEBUG is defined) */
-#define CRYPTO_malloc_debug_init()	do {\
-	CRYPTO_set_mem_debug_functions(\
-		CRYPTO_dbg_malloc,\
-		CRYPTO_dbg_realloc,\
-		CRYPTO_dbg_free,\
-		CRYPTO_dbg_set_options,\
-		CRYPTO_dbg_get_options);\
-	} while(0)
+void CRYPTO_malloc_debug_init(void);
 
 int CRYPTO_mem_ctrl(int mode);
 int CRYPTO_is_mem_check_on(void);
@@ -363,6 +362,7 @@
 #define is_MemCheck_on() CRYPTO_is_mem_check_on()
 
 #define OPENSSL_malloc(num)	CRYPTO_malloc((int)num,__FILE__,__LINE__)
+#define OPENSSL_strdup(str)	CRYPTO_strdup((str),__FILE__,__LINE__)
 #define OPENSSL_realloc(addr,num) \
 	CRYPTO_realloc((char *)addr,(int)num,__FILE__,__LINE__)
 #define OPENSSL_realloc_clean(addr,old_num,num) \
@@ -427,6 +427,9 @@
 int CRYPTO_add_lock(int *pointer,int amount,int type, const char *file,
 		    int line);
 
+void int_CRYPTO_set_do_dynlock_callback(
+	void (*do_dynlock_cb)(int mode, int type, const char *file, int line));
+
 int CRYPTO_get_new_dynlockid(void);
 void CRYPTO_destroy_dynlockid(int i);
 struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i);
@@ -451,6 +454,10 @@
 				   void (*f)(void *,int),
 				   void (*so)(long),
 				   long (*go)(void));
+void CRYPTO_set_mem_info_functions(
+	int  (*push_info_fn)(const char *info, const char *file, int line),
+	int  (*pop_info_fn)(void),
+	int (*remove_all_info_fn)(void));
 void CRYPTO_get_mem_functions(void *(**m)(size_t),void *(**r)(void *, size_t), void (**f)(void *));
 void CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *));
 void CRYPTO_get_mem_ex_functions(void *(**m)(size_t,const char *,int),
@@ -467,6 +474,7 @@
 void *CRYPTO_malloc_locked(int num, const char *file, int line);
 void CRYPTO_free_locked(void *);
 void *CRYPTO_malloc(int num, const char *file, int line);
+char *CRYPTO_strdup(const char *str, const char *file, int line);
 void CRYPTO_free(void *);
 void *CRYPTO_realloc(void *addr,int num, const char *file, int line);
 void *CRYPTO_realloc_clean(void *addr,int old_num,int num,const char *file,
@@ -506,6 +514,9 @@
 void CRYPTO_dbg_set_options(long bits);
 long CRYPTO_dbg_get_options(void);
 
+int CRYPTO_dbg_push_info(const char *info, const char *file, int line);
+int CRYPTO_dbg_pop_info(void);
+int CRYPTO_dbg_remove_all_info(void);
 
 #ifndef OPENSSL_NO_FP_API
 void CRYPTO_mem_leaks_fp(FILE *);
@@ -521,6 +532,61 @@
 
 unsigned long *OPENSSL_ia32cap_loc(void);
 #define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc()))
+int OPENSSL_isservice(void);
+
+#ifdef OPENSSL_FIPS
+#define FIPS_ERROR_IGNORED(alg) OpenSSLDie(__FILE__, __LINE__, \
+		alg " previous FIPS forbidden algorithm error ignored");
+
+#define FIPS_BAD_ABORT(alg) OpenSSLDie(__FILE__, __LINE__, \
+		#alg " Algorithm forbidden in FIPS mode");
+
+#ifdef OPENSSL_FIPS_STRICT
+#define FIPS_BAD_ALGORITHM(alg) FIPS_BAD_ABORT(alg)
+#else
+#define FIPS_BAD_ALGORITHM(alg) \
+	{ \
+	FIPSerr(FIPS_F_HASH_FINAL,FIPS_R_NON_FIPS_METHOD); \
+	ERR_add_error_data(2, "Algorithm=", #alg); \
+	return 0; \
+	}
+#endif
+
+/* Low level digest API blocking macro */
+
+#define FIPS_NON_FIPS_MD_Init(alg) \
+	int alg##_Init(alg##_CTX *c) \
+		{ \
+		if (FIPS_mode()) \
+			FIPS_BAD_ALGORITHM(alg) \
+		return private_##alg##_Init(c); \
+		} \
+	int private_##alg##_Init(alg##_CTX *c)
+
+/* For ciphers the API often varies from cipher to cipher and each needs to
+ * be treated as a special case. Variable key length ciphers (Blowfish, RC4,
+ * CAST) however are very similar and can use a blocking macro.
+ */
+
+#define FIPS_NON_FIPS_VCIPHER_Init(alg) \
+	void alg##_set_key(alg##_KEY *key, int len, const unsigned char *data) \
+		{ \
+		if (FIPS_mode()) \
+			FIPS_BAD_ABORT(alg) \
+		private_##alg##_set_key(key, len, data); \
+		} \
+	void private_##alg##_set_key(alg##_KEY *key, int len, \
+					const unsigned char *data)
+
+#else
+
+#define FIPS_NON_FIPS_VCIPHER_Init(alg) \
+	void alg##_set_key(alg##_KEY *key, int len, const unsigned char *data)
+
+#define FIPS_NON_FIPS_MD_Init(alg) \
+	int alg##_Init(alg##_CTX *c) 
+
+#endif /* def OPENSSL_FIPS */
 
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -528,6 +594,9 @@
  */
 void ERR_load_CRYPTO_strings(void);
 
+#define OPENSSL_HAVE_INIT	1
+void OPENSSL_init(void);
+
 /* Error codes for the CRYPTO functions. */
 
 /* Function codes. */
diff --git a/crypto/des/Makefile b/crypto/des/Makefile
index 523dfe3..786e688 100644
--- a/crypto/des/Makefile
+++ b/crypto/des/Makefile
@@ -24,7 +24,7 @@
 APPS=
 
 LIB=$(TOP)/libcrypto.a
-LIBSRC=	cbc_cksm.c cbc_enc.c  cfb64enc.c cfb_enc.c  \
+LIBSRC=	des_lib.c cbc_cksm.c cbc_enc.c  cfb64enc.c cfb_enc.c  \
 	ecb3_enc.c ecb_enc.c  enc_read.c enc_writ.c \
 	fcrypt.c ofb64enc.c ofb_enc.c  pcbc_enc.c \
 	qud_cksm.c rand_key.c rpc_enc.c  set_key.c  \
@@ -33,7 +33,7 @@
 	str2key.c  cfb64ede.c ofb64ede.c ede_cbcm_enc.c des_old.c des_old2.c \
 	read2pwd.c
 
-LIBOBJ= set_key.o  ecb_enc.o  cbc_enc.o \
+LIBOBJ= des_lib.o set_key.o  ecb_enc.o  cbc_enc.o \
 	ecb3_enc.o cfb64enc.o cfb64ede.o cfb_enc.o  ofb64ede.o \
 	enc_read.o enc_writ.o ofb64enc.o \
 	ofb_enc.o  str2key.o  pcbc_enc.o qud_cksm.o rand_key.o \
@@ -54,7 +54,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -157,6 +157,13 @@
 des_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 des_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
 des_enc.o: des_enc.c des_locl.h ncbc_enc.c
+des_lib.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+des_lib.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+des_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+des_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+des_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+des_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+des_lib.o: ../../include/openssl/ui_compat.h des_lib.c des_locl.h des_ver.h
 des_old.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
 des_old.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
 des_old.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
@@ -175,14 +182,12 @@
 ecb3_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 ecb3_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
 ecb3_enc.o: des_locl.h ecb3_enc.c
-ecb_enc.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
 ecb_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
 ecb_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-ecb_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ecb_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ecb_enc.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
-ecb_enc.o: ../../include/openssl/ui_compat.h des_locl.h des_ver.h ecb_enc.c
-ecb_enc.o: spr.h
+ecb_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+ecb_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ecb_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+ecb_enc.o: des_locl.h ecb_enc.c spr.h
 ede_cbcm_enc.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
 ede_cbcm_enc.o: ../../include/openssl/e_os2.h
 ede_cbcm_enc.o: ../../include/openssl/opensslconf.h
@@ -272,11 +277,11 @@
 rpc_enc.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
 rpc_enc.o: des_locl.h des_ver.h rpc_des.h rpc_enc.c
 set_key.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-set_key.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-set_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-set_key.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-set_key.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-set_key.o: des_locl.h set_key.c
+set_key.o: ../../include/openssl/e_os2.h ../../include/openssl/fips.h
+set_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/ossl_typ.h
+set_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+set_key.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+set_key.o: ../../include/openssl/ui_compat.h des_locl.h set_key.c
 str2key.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
 str2key.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
 str2key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
diff --git a/crypto/des/asm/des_enc.m4 b/crypto/des/asm/des_enc.m4
index f5b1928..f59333a 100644
--- a/crypto/des/asm/des_enc.m4
+++ b/crypto/des/asm/des_enc.m4
@@ -44,6 +44,7 @@
 !
 
 .ident "des_enc.m4 2.1"
+.file  "des_enc-sparc.S"
 
 #if defined(__SUNPRO_C) && defined(__sparcv9)
 # define ABI64  /* They've said -xarch=v9 at command line */
@@ -315,16 +316,16 @@
 	ld	[global1+local1], local1
 	xor	$2, out1, out1            ! 8642
 	xor	$2, out0, out0            ! 7531
-	fmovs	%f0, %f0                  ! fxor used for alignment
+	! fmovs	%f0, %f0                  ! fxor used for alignment
 
 	srl	out1, 4, local0           ! rotate 4 right
 	and	out0, local5, local3      ! 3
-	fmovs	%f0, %f0
+	! fmovs	%f0, %f0
 
 	ld	[$5+$3*8], local7         ! key 7531 next round
 	srl	local3, 8, local3         ! 3
 	and	local0, 252, local2       ! 2
-	fmovs	%f0, %f0
+	! fmovs	%f0, %f0
 
 	ld	[global3+local3],local3   ! 3
 	sll	out1, 28, out1            ! rotate
@@ -1179,8 +1180,11 @@
 
 	save	%sp, FRAME, %sp
 
-	call	.PIC.me.up
-	mov	.PIC.me.up-(.-4),out0
+	sethi	%hi(.PIC.DES_SPtrans-1f),global1
+	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
+1:	call	.+8
+	add	%o7,global1,global1
+	sub	global1,.PIC.DES_SPtrans-.des_and,out2
 
 	ld	[in0], in5                ! left
 	cmp	in2, 0                    ! enc
@@ -1237,8 +1241,11 @@
 
 	save	%sp, FRAME, %sp
 
-	call	.PIC.me.up
-	mov	.PIC.me.up-(.-4),out0
+	sethi	%hi(.PIC.DES_SPtrans-1f),global1
+	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
+1:	call	.+8
+	add	%o7,global1,global1
+	sub	global1,.PIC.DES_SPtrans-.des_and,out2
 
 	! Set sbox address 1 to 6 and rotate halfs 3 left
 	! Errors caught by destest? Yes. Still? *NO*
@@ -1352,8 +1359,11 @@
 
 	save	%sp, FRAME, %sp
 	
-	call	.PIC.me.up
-	mov	.PIC.me.up-(.-4),out0
+	sethi	%hi(.PIC.DES_SPtrans-1f),global1
+	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
+1:	call	.+8
+	add	%o7,global1,global1
+	sub	global1,.PIC.DES_SPtrans-.des_and,out2
 
 	ld	[in0], in5                ! left
 	add	in2, 120, in4             ! ks2
@@ -1394,8 +1404,11 @@
 
 	save	%sp, FRAME, %sp
 	
-	call	.PIC.me.up
-	mov	.PIC.me.up-(.-4),out0
+	sethi	%hi(.PIC.DES_SPtrans-1f),global1
+	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
+1:	call	.+8
+	add	%o7,global1,global1
+	sub	global1,.PIC.DES_SPtrans-.des_and,out2
 
 	ld	[in0], in5                ! left
 	add	in3, 120, in4             ! ks3
@@ -1424,105 +1437,6 @@
 .DES_decrypt3.end:
 	.size	 DES_decrypt3,.DES_decrypt3.end-DES_decrypt3
 
-	.align	256
-	.type	 .des_and,#object
-	.size	 .des_and,284
-
-.des_and:
-
-! This table is used for AND 0xFC when it is known that register
-! bits 8-31 are zero. Makes it possible to do three arithmetic
-! operations in one cycle.
-
-	.byte  0, 0, 0, 0, 4, 4, 4, 4
-	.byte  8, 8, 8, 8, 12, 12, 12, 12
-	.byte  16, 16, 16, 16, 20, 20, 20, 20
-	.byte  24, 24, 24, 24, 28, 28, 28, 28
-	.byte  32, 32, 32, 32, 36, 36, 36, 36
-	.byte  40, 40, 40, 40, 44, 44, 44, 44
-	.byte  48, 48, 48, 48, 52, 52, 52, 52
-	.byte  56, 56, 56, 56, 60, 60, 60, 60
-	.byte  64, 64, 64, 64, 68, 68, 68, 68
-	.byte  72, 72, 72, 72, 76, 76, 76, 76
-	.byte  80, 80, 80, 80, 84, 84, 84, 84
-	.byte  88, 88, 88, 88, 92, 92, 92, 92
-	.byte  96, 96, 96, 96, 100, 100, 100, 100
-	.byte  104, 104, 104, 104, 108, 108, 108, 108
-	.byte  112, 112, 112, 112, 116, 116, 116, 116
-	.byte  120, 120, 120, 120, 124, 124, 124, 124
-	.byte  128, 128, 128, 128, 132, 132, 132, 132
-	.byte  136, 136, 136, 136, 140, 140, 140, 140
-	.byte  144, 144, 144, 144, 148, 148, 148, 148
-	.byte  152, 152, 152, 152, 156, 156, 156, 156
-	.byte  160, 160, 160, 160, 164, 164, 164, 164
-	.byte  168, 168, 168, 168, 172, 172, 172, 172
-	.byte  176, 176, 176, 176, 180, 180, 180, 180
-	.byte  184, 184, 184, 184, 188, 188, 188, 188
-	.byte  192, 192, 192, 192, 196, 196, 196, 196
-	.byte  200, 200, 200, 200, 204, 204, 204, 204
-	.byte  208, 208, 208, 208, 212, 212, 212, 212
-	.byte  216, 216, 216, 216, 220, 220, 220, 220
-	.byte  224, 224, 224, 224, 228, 228, 228, 228
-	.byte  232, 232, 232, 232, 236, 236, 236, 236
-	.byte  240, 240, 240, 240, 244, 244, 244, 244
-	.byte  248, 248, 248, 248, 252, 252, 252, 252
-
-	! 5 numbers for initil/final permutation
-
-	.word   0x0f0f0f0f                ! offset 256
-	.word	0x0000ffff                ! 260
-	.word	0x33333333                ! 264
-	.word	0x00ff00ff                ! 268
-	.word	0x55555555                ! 272
-
-	.word	0                         ! 276
-	.word	LOOPS                     ! 280
-	.word	0x0000FC00                ! 284
-.PIC.DES_SPtrans:
-	.word	%r_disp32(DES_SPtrans)
-
-! input:	out0	offset between .PIC.me.up and caller
-! output:	out0	pointer to .PIC.me.up
-!		out2	pointer to .des_and
-!		global1	pointer to DES_SPtrans
-	.align	32
-.PIC.me.up:
-	add	out0,%o7,out0			! pointer to .PIC.me.up
-#if 1
-	ld	[out0+(.PIC.DES_SPtrans-.PIC.me.up)],global1
-	add	global1,(.PIC.DES_SPtrans-.PIC.me.up),global1
-	add	global1,out0,global1
-#else
-# ifdef OPENSSL_PIC
-	! In case anybody wonders why this code is same for both ABI.
-	! To start with it is not. Do note LDPTR below. But of course
-	! you must be wondering why the rest of it does not contain
-	! things like %hh, %hm and %lm. Well, those are needed only
-	! if OpenSSL library *itself* will become larger than 4GB,
-	! which is not going to happen any time soon. 
-	sethi	%hi(DES_SPtrans),global1
-	or	global1,%lo(DES_SPtrans),global1
-	sethi	%hi(_GLOBAL_OFFSET_TABLE_-(.PIC.me.up-.)),out2
-	add	global1,out0,global1
-	add	out2,%lo(_GLOBAL_OFFSET_TABLE_-(.PIC.me.up-.)),out2
-	LDPTR	[out2+global1],global1
-# elif 0
-	setn	DES_SPtrans,out2,global1	! synthetic instruction !
-# elif defined(ABI64)
-	sethi	%hh(DES_SPtrans),out2
-	or	out2,%hm(DES_SPtrans),out2
-	sethi	%lm(DES_SPtrans),global1
-	or	global1,%lo(DES_SPtrans),global1
-	sllx	out2,32,out2
-	or	out2,global1,global1
-# else
-	sethi	%hi(DES_SPtrans),global1
-	or	global1,%lo(DES_SPtrans),global1
-# endif
-#endif
-	retl
-	add	out0,.des_and-.PIC.me.up,out2
-
 ! void DES_ncbc_encrypt(input, output, length, schedule, ivec, enc)
 ! *****************************************************************
 
@@ -1539,8 +1453,11 @@
 	define({OUTPUT}, { [%sp+BIAS+ARG0+1*ARGSZ] })
 	define({IVEC},   { [%sp+BIAS+ARG0+4*ARGSZ] })
 
-	call	.PIC.me.up
-	mov	.PIC.me.up-(.-4),out0
+	sethi	%hi(.PIC.DES_SPtrans-1f),global1
+	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
+1:	call	.+8
+	add	%o7,global1,global1
+	sub	global1,.PIC.DES_SPtrans-.des_and,out2
 
 	cmp	in5, 0                    ! enc   
 
@@ -1761,8 +1678,11 @@
 	define({KS2}, { [%sp+BIAS+ARG0+4*ARGSZ] })
 	define({KS3}, { [%sp+BIAS+ARG0+5*ARGSZ] })
 
-	call	.PIC.me.up
-	mov	.PIC.me.up-(.-4),out0
+	sethi	%hi(.PIC.DES_SPtrans-1f),global1
+	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
+1:	call	.+8
+	add	%o7,global1,global1
+	sub	global1,.PIC.DES_SPtrans-.des_and,out2
 
 	LDPTR	[%fp+BIAS+ARG0+7*ARGSZ], local3          ! enc
 	LDPTR	[%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
@@ -1978,3 +1898,200 @@
 
 .DES_ede3_cbc_encrypt.end:
 	.size	 DES_ede3_cbc_encrypt,.DES_ede3_cbc_encrypt.end-DES_ede3_cbc_encrypt
+
+	.align	256
+	.type	 .des_and,#object
+	.size	 .des_and,284
+
+.des_and:
+
+! This table is used for AND 0xFC when it is known that register
+! bits 8-31 are zero. Makes it possible to do three arithmetic
+! operations in one cycle.
+
+	.byte  0, 0, 0, 0, 4, 4, 4, 4
+	.byte  8, 8, 8, 8, 12, 12, 12, 12
+	.byte  16, 16, 16, 16, 20, 20, 20, 20
+	.byte  24, 24, 24, 24, 28, 28, 28, 28
+	.byte  32, 32, 32, 32, 36, 36, 36, 36
+	.byte  40, 40, 40, 40, 44, 44, 44, 44
+	.byte  48, 48, 48, 48, 52, 52, 52, 52
+	.byte  56, 56, 56, 56, 60, 60, 60, 60
+	.byte  64, 64, 64, 64, 68, 68, 68, 68
+	.byte  72, 72, 72, 72, 76, 76, 76, 76
+	.byte  80, 80, 80, 80, 84, 84, 84, 84
+	.byte  88, 88, 88, 88, 92, 92, 92, 92
+	.byte  96, 96, 96, 96, 100, 100, 100, 100
+	.byte  104, 104, 104, 104, 108, 108, 108, 108
+	.byte  112, 112, 112, 112, 116, 116, 116, 116
+	.byte  120, 120, 120, 120, 124, 124, 124, 124
+	.byte  128, 128, 128, 128, 132, 132, 132, 132
+	.byte  136, 136, 136, 136, 140, 140, 140, 140
+	.byte  144, 144, 144, 144, 148, 148, 148, 148
+	.byte  152, 152, 152, 152, 156, 156, 156, 156
+	.byte  160, 160, 160, 160, 164, 164, 164, 164
+	.byte  168, 168, 168, 168, 172, 172, 172, 172
+	.byte  176, 176, 176, 176, 180, 180, 180, 180
+	.byte  184, 184, 184, 184, 188, 188, 188, 188
+	.byte  192, 192, 192, 192, 196, 196, 196, 196
+	.byte  200, 200, 200, 200, 204, 204, 204, 204
+	.byte  208, 208, 208, 208, 212, 212, 212, 212
+	.byte  216, 216, 216, 216, 220, 220, 220, 220
+	.byte  224, 224, 224, 224, 228, 228, 228, 228
+	.byte  232, 232, 232, 232, 236, 236, 236, 236
+	.byte  240, 240, 240, 240, 244, 244, 244, 244
+	.byte  248, 248, 248, 248, 252, 252, 252, 252
+
+	! 5 numbers for initil/final permutation
+
+	.word   0x0f0f0f0f                ! offset 256
+	.word	0x0000ffff                ! 260
+	.word	0x33333333                ! 264
+	.word	0x00ff00ff                ! 268
+	.word	0x55555555                ! 272
+
+	.word	0                         ! 276
+	.word	LOOPS                     ! 280
+	.word	0x0000FC00                ! 284
+
+	.type	.PIC.DES_SPtrans,#object
+	.size	.PIC.DES_SPtrans,2048
+.align	64
+.PIC.DES_SPtrans:
+	! nibble 0
+	.word	0x02080800, 0x00080000, 0x02000002, 0x02080802
+	.word	0x02000000, 0x00080802, 0x00080002, 0x02000002
+	.word	0x00080802, 0x02080800, 0x02080000, 0x00000802
+	.word	0x02000802, 0x02000000, 0x00000000, 0x00080002
+	.word	0x00080000, 0x00000002, 0x02000800, 0x00080800
+	.word	0x02080802, 0x02080000, 0x00000802, 0x02000800
+	.word	0x00000002, 0x00000800, 0x00080800, 0x02080002
+	.word	0x00000800, 0x02000802, 0x02080002, 0x00000000
+	.word	0x00000000, 0x02080802, 0x02000800, 0x00080002
+	.word	0x02080800, 0x00080000, 0x00000802, 0x02000800
+	.word	0x02080002, 0x00000800, 0x00080800, 0x02000002
+	.word	0x00080802, 0x00000002, 0x02000002, 0x02080000
+	.word	0x02080802, 0x00080800, 0x02080000, 0x02000802
+	.word	0x02000000, 0x00000802, 0x00080002, 0x00000000
+	.word	0x00080000, 0x02000000, 0x02000802, 0x02080800
+	.word	0x00000002, 0x02080002, 0x00000800, 0x00080802
+	! nibble 1
+	.word	0x40108010, 0x00000000, 0x00108000, 0x40100000
+	.word	0x40000010, 0x00008010, 0x40008000, 0x00108000
+	.word	0x00008000, 0x40100010, 0x00000010, 0x40008000
+	.word	0x00100010, 0x40108000, 0x40100000, 0x00000010
+	.word	0x00100000, 0x40008010, 0x40100010, 0x00008000
+	.word	0x00108010, 0x40000000, 0x00000000, 0x00100010
+	.word	0x40008010, 0x00108010, 0x40108000, 0x40000010
+	.word	0x40000000, 0x00100000, 0x00008010, 0x40108010
+	.word	0x00100010, 0x40108000, 0x40008000, 0x00108010
+	.word	0x40108010, 0x00100010, 0x40000010, 0x00000000
+	.word	0x40000000, 0x00008010, 0x00100000, 0x40100010
+	.word	0x00008000, 0x40000000, 0x00108010, 0x40008010
+	.word	0x40108000, 0x00008000, 0x00000000, 0x40000010
+	.word	0x00000010, 0x40108010, 0x00108000, 0x40100000
+	.word	0x40100010, 0x00100000, 0x00008010, 0x40008000
+	.word	0x40008010, 0x00000010, 0x40100000, 0x00108000
+	! nibble 2
+	.word	0x04000001, 0x04040100, 0x00000100, 0x04000101
+	.word	0x00040001, 0x04000000, 0x04000101, 0x00040100
+	.word	0x04000100, 0x00040000, 0x04040000, 0x00000001
+	.word	0x04040101, 0x00000101, 0x00000001, 0x04040001
+	.word	0x00000000, 0x00040001, 0x04040100, 0x00000100
+	.word	0x00000101, 0x04040101, 0x00040000, 0x04000001
+	.word	0x04040001, 0x04000100, 0x00040101, 0x04040000
+	.word	0x00040100, 0x00000000, 0x04000000, 0x00040101
+	.word	0x04040100, 0x00000100, 0x00000001, 0x00040000
+	.word	0x00000101, 0x00040001, 0x04040000, 0x04000101
+	.word	0x00000000, 0x04040100, 0x00040100, 0x04040001
+	.word	0x00040001, 0x04000000, 0x04040101, 0x00000001
+	.word	0x00040101, 0x04000001, 0x04000000, 0x04040101
+	.word	0x00040000, 0x04000100, 0x04000101, 0x00040100
+	.word	0x04000100, 0x00000000, 0x04040001, 0x00000101
+	.word	0x04000001, 0x00040101, 0x00000100, 0x04040000
+	! nibble 3
+	.word	0x00401008, 0x10001000, 0x00000008, 0x10401008
+	.word	0x00000000, 0x10400000, 0x10001008, 0x00400008
+	.word	0x10401000, 0x10000008, 0x10000000, 0x00001008
+	.word	0x10000008, 0x00401008, 0x00400000, 0x10000000
+	.word	0x10400008, 0x00401000, 0x00001000, 0x00000008
+	.word	0x00401000, 0x10001008, 0x10400000, 0x00001000
+	.word	0x00001008, 0x00000000, 0x00400008, 0x10401000
+	.word	0x10001000, 0x10400008, 0x10401008, 0x00400000
+	.word	0x10400008, 0x00001008, 0x00400000, 0x10000008
+	.word	0x00401000, 0x10001000, 0x00000008, 0x10400000
+	.word	0x10001008, 0x00000000, 0x00001000, 0x00400008
+	.word	0x00000000, 0x10400008, 0x10401000, 0x00001000
+	.word	0x10000000, 0x10401008, 0x00401008, 0x00400000
+	.word	0x10401008, 0x00000008, 0x10001000, 0x00401008
+	.word	0x00400008, 0x00401000, 0x10400000, 0x10001008
+	.word	0x00001008, 0x10000000, 0x10000008, 0x10401000
+	! nibble 4
+	.word	0x08000000, 0x00010000, 0x00000400, 0x08010420
+	.word	0x08010020, 0x08000400, 0x00010420, 0x08010000
+	.word	0x00010000, 0x00000020, 0x08000020, 0x00010400
+	.word	0x08000420, 0x08010020, 0x08010400, 0x00000000
+	.word	0x00010400, 0x08000000, 0x00010020, 0x00000420
+	.word	0x08000400, 0x00010420, 0x00000000, 0x08000020
+	.word	0x00000020, 0x08000420, 0x08010420, 0x00010020
+	.word	0x08010000, 0x00000400, 0x00000420, 0x08010400
+	.word	0x08010400, 0x08000420, 0x00010020, 0x08010000
+	.word	0x00010000, 0x00000020, 0x08000020, 0x08000400
+	.word	0x08000000, 0x00010400, 0x08010420, 0x00000000
+	.word	0x00010420, 0x08000000, 0x00000400, 0x00010020
+	.word	0x08000420, 0x00000400, 0x00000000, 0x08010420
+	.word	0x08010020, 0x08010400, 0x00000420, 0x00010000
+	.word	0x00010400, 0x08010020, 0x08000400, 0x00000420
+	.word	0x00000020, 0x00010420, 0x08010000, 0x08000020
+	! nibble 5
+	.word	0x80000040, 0x00200040, 0x00000000, 0x80202000
+	.word	0x00200040, 0x00002000, 0x80002040, 0x00200000
+	.word	0x00002040, 0x80202040, 0x00202000, 0x80000000
+	.word	0x80002000, 0x80000040, 0x80200000, 0x00202040
+	.word	0x00200000, 0x80002040, 0x80200040, 0x00000000
+	.word	0x00002000, 0x00000040, 0x80202000, 0x80200040
+	.word	0x80202040, 0x80200000, 0x80000000, 0x00002040
+	.word	0x00000040, 0x00202000, 0x00202040, 0x80002000
+	.word	0x00002040, 0x80000000, 0x80002000, 0x00202040
+	.word	0x80202000, 0x00200040, 0x00000000, 0x80002000
+	.word	0x80000000, 0x00002000, 0x80200040, 0x00200000
+	.word	0x00200040, 0x80202040, 0x00202000, 0x00000040
+	.word	0x80202040, 0x00202000, 0x00200000, 0x80002040
+	.word	0x80000040, 0x80200000, 0x00202040, 0x00000000
+	.word	0x00002000, 0x80000040, 0x80002040, 0x80202000
+	.word	0x80200000, 0x00002040, 0x00000040, 0x80200040
+	! nibble 6
+	.word	0x00004000, 0x00000200, 0x01000200, 0x01000004
+	.word	0x01004204, 0x00004004, 0x00004200, 0x00000000
+	.word	0x01000000, 0x01000204, 0x00000204, 0x01004000
+	.word	0x00000004, 0x01004200, 0x01004000, 0x00000204
+	.word	0x01000204, 0x00004000, 0x00004004, 0x01004204
+	.word	0x00000000, 0x01000200, 0x01000004, 0x00004200
+	.word	0x01004004, 0x00004204, 0x01004200, 0x00000004
+	.word	0x00004204, 0x01004004, 0x00000200, 0x01000000
+	.word	0x00004204, 0x01004000, 0x01004004, 0x00000204
+	.word	0x00004000, 0x00000200, 0x01000000, 0x01004004
+	.word	0x01000204, 0x00004204, 0x00004200, 0x00000000
+	.word	0x00000200, 0x01000004, 0x00000004, 0x01000200
+	.word	0x00000000, 0x01000204, 0x01000200, 0x00004200
+	.word	0x00000204, 0x00004000, 0x01004204, 0x01000000
+	.word	0x01004200, 0x00000004, 0x00004004, 0x01004204
+	.word	0x01000004, 0x01004200, 0x01004000, 0x00004004
+	! nibble 7
+	.word	0x20800080, 0x20820000, 0x00020080, 0x00000000
+	.word	0x20020000, 0x00800080, 0x20800000, 0x20820080
+	.word	0x00000080, 0x20000000, 0x00820000, 0x00020080
+	.word	0x00820080, 0x20020080, 0x20000080, 0x20800000
+	.word	0x00020000, 0x00820080, 0x00800080, 0x20020000
+	.word	0x20820080, 0x20000080, 0x00000000, 0x00820000
+	.word	0x20000000, 0x00800000, 0x20020080, 0x20800080
+	.word	0x00800000, 0x00020000, 0x20820000, 0x00000080
+	.word	0x00800000, 0x00020000, 0x20000080, 0x20820080
+	.word	0x00020080, 0x20000000, 0x00000000, 0x00820000
+	.word	0x20800080, 0x20020080, 0x20020000, 0x00800080
+	.word	0x20820000, 0x00000080, 0x00800080, 0x20020000
+	.word	0x20820080, 0x00800000, 0x20800000, 0x20000080
+	.word	0x00820000, 0x00020080, 0x20020080, 0x20800000
+	.word	0x00000080, 0x20820000, 0x00820080, 0x00000000
+	.word	0x20000000, 0x20800080, 0x00020000, 0x00820080
+
diff --git a/crypto/des/des_enc.c b/crypto/des/des_enc.c
index 1c37ab9..cf71965 100644
--- a/crypto/des/des_enc.c
+++ b/crypto/des/des_enc.c
@@ -289,6 +289,8 @@
 
 #ifndef DES_DEFAULT_OPTIONS
 
+#if !defined(OPENSSL_FIPS_DES_ASM)
+
 #undef CBC_ENC_C__DONT_UPDATE_IV
 #include "ncbc_enc.c" /* DES_ncbc_encrypt */
 
@@ -404,4 +406,6 @@
 	tin[0]=tin[1]=0;
 	}
 
+#endif
+
 #endif /* DES_DEFAULT_OPTIONS */
diff --git a/crypto/des/des_lib.c b/crypto/des/des_lib.c
new file mode 100644
index 0000000..d4b3047
--- /dev/null
+++ b/crypto/des/des_lib.c
@@ -0,0 +1,106 @@
+/* crypto/des/ecb_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+#include "des_ver.h"
+#include <openssl/opensslv.h>
+#include <openssl/bio.h>
+
+OPENSSL_GLOBAL const char libdes_version[]="libdes" OPENSSL_VERSION_PTEXT;
+OPENSSL_GLOBAL const char DES_version[]="DES" OPENSSL_VERSION_PTEXT;
+
+const char *DES_options(void)
+	{
+	static int init=1;
+	static char buf[32];
+
+	if (init)
+		{
+		const char *ptr,*unroll,*risc,*size;
+
+#ifdef DES_PTR
+		ptr="ptr";
+#else
+		ptr="idx";
+#endif
+#if defined(DES_RISC1) || defined(DES_RISC2)
+#ifdef DES_RISC1
+		risc="risc1";
+#endif
+#ifdef DES_RISC2
+		risc="risc2";
+#endif
+#else
+		risc="cisc";
+#endif
+#ifdef DES_UNROLL
+		unroll="16";
+#else
+		unroll="4";
+#endif
+		if (sizeof(DES_LONG) != sizeof(long))
+			size="int";
+		else
+			size="long";
+		BIO_snprintf(buf,sizeof buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,
+			     size);
+		init=0;
+		}
+	return(buf);
+	}
+
diff --git a/crypto/des/ecb_enc.c b/crypto/des/ecb_enc.c
index 00d5b91..75ae6cf 100644
--- a/crypto/des/ecb_enc.c
+++ b/crypto/des/ecb_enc.c
@@ -57,54 +57,7 @@
  */
 
 #include "des_locl.h"
-#include "des_ver.h"
 #include "spr.h"
-#include <openssl/opensslv.h>
-#include <openssl/bio.h>
-
-OPENSSL_GLOBAL const char libdes_version[]="libdes" OPENSSL_VERSION_PTEXT;
-OPENSSL_GLOBAL const char DES_version[]="DES" OPENSSL_VERSION_PTEXT;
-
-const char *DES_options(void)
-	{
-	static int init=1;
-	static char buf[32];
-
-	if (init)
-		{
-		const char *ptr,*unroll,*risc,*size;
-
-#ifdef DES_PTR
-		ptr="ptr";
-#else
-		ptr="idx";
-#endif
-#if defined(DES_RISC1) || defined(DES_RISC2)
-#ifdef DES_RISC1
-		risc="risc1";
-#endif
-#ifdef DES_RISC2
-		risc="risc2";
-#endif
-#else
-		risc="cisc";
-#endif
-#ifdef DES_UNROLL
-		unroll="16";
-#else
-		unroll="4";
-#endif
-		if (sizeof(DES_LONG) != sizeof(long))
-			size="int";
-		else
-			size="long";
-		BIO_snprintf(buf,sizeof buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,
-			     size);
-		init=0;
-		}
-	return(buf);
-	}
-		
 
 void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output,
 		     DES_key_schedule *ks, int enc)
diff --git a/crypto/des/enc_read.c b/crypto/des/enc_read.c
index c70fb68..e7da2ec 100644
--- a/crypto/des/enc_read.c
+++ b/crypto/des/enc_read.c
@@ -147,7 +147,11 @@
 	/* first - get the length */
 	while (net_num < HDRSIZE) 
 		{
+#ifndef _WIN32
 		i=read(fd,(void *)&(net[net_num]),HDRSIZE-net_num);
+#else
+		i=_read(fd,(void *)&(net[net_num]),HDRSIZE-net_num);
+#endif
 #ifdef EINTR
 		if ((i == -1) && (errno == EINTR)) continue;
 #endif
diff --git a/crypto/des/enc_writ.c b/crypto/des/enc_writ.c
index af5b8c2..c2f032c 100644
--- a/crypto/des/enc_writ.c
+++ b/crypto/des/enc_writ.c
@@ -153,7 +153,11 @@
 		{
 		/* eay 26/08/92 I was not doing writing from where we
 		 * got up to. */
+#ifndef _WIN32
 		i=write(fd,(void *)&(outbuf[j]),outnum-j);
+#else
+		i=_write(fd,(void *)&(outbuf[j]),outnum-j);
+#endif
 		if (i == -1)
 			{
 #ifdef EINTR
diff --git a/crypto/des/set_key.c b/crypto/des/set_key.c
index a43ef3c..c0806d5 100644
--- a/crypto/des/set_key.c
+++ b/crypto/des/set_key.c
@@ -64,6 +64,10 @@
  * 1.0 First working version
  */
 #include "des_locl.h"
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 
 OPENSSL_IMPLEMENT_GLOBAL(int,DES_check_key);	/* defaults to false */
 
@@ -349,6 +353,10 @@
 	k = &schedule->ks->deslong[0];
 	in = &(*key)[0];
 
+#ifdef OPENSSL_FIPS
+	FIPS_selftest_check();
+#endif
+
 	c2l(in,c);
 	c2l(in,d);
 
@@ -405,3 +413,4 @@
 	des_set_odd_parity(key);
 	}
 */
+
diff --git a/crypto/des/times/usparc.cc b/crypto/des/times/usparc.cc
index f6ec8e8..0864285 100644
--- a/crypto/des/times/usparc.cc
+++ b/crypto/des/times/usparc.cc
@@ -2,7 +2,7 @@
 
 For the ultra sparc, SunC 4.0 cc -fast -Xa -xO5, running 'des_opts'
 gives a speed of 475,000 des/s while 'speed' gives 417,000 des/s.
-I belive the difference is tied up in optimisation that the compiler
+I believe the difference is tied up in optimisation that the compiler
 is able to perform when the code is 'inlined'.  For 'speed', the DES
 routines are being linked from a library.  I'll record the higher
 speed since if performance is everything, you can always inline
diff --git a/crypto/dh/Makefile b/crypto/dh/Makefile
index d368e33..d01fa96 100644
--- a/crypto/dh/Makefile
+++ b/crypto/dh/Makefile
@@ -33,7 +33,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -123,11 +123,17 @@
 dh_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
 dh_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 dh_key.o: ../../include/openssl/symhacks.h ../cryptlib.h dh_key.c
-dh_lib.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
-dh_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-dh_lib.o: ../../include/openssl/dh.h ../../include/openssl/e_os2.h
+dh_lib.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
+dh_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+dh_lib.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
+dh_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+dh_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 dh_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
-dh_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+dh_lib.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+dh_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+dh_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 dh_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-dh_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-dh_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h dh_lib.c
+dh_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+dh_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dh_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+dh_lib.o: ../../include/openssl/x509_vfy.h ../cryptlib.h dh_lib.c
diff --git a/crypto/dh/dh.h b/crypto/dh/dh.h
index ccdf35a..10475ac 100644
--- a/crypto/dh/dh.h
+++ b/crypto/dh/dh.h
@@ -77,6 +77,8 @@
 # define OPENSSL_DH_MAX_MODULUS_BITS	10000
 #endif
 
+#define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024
+
 #define DH_FLAG_CACHE_MONT_P     0x01
 #define DH_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DH
                                        * implementation now uses constant time
@@ -167,6 +169,11 @@
 
 const DH_METHOD *DH_OpenSSL(void);
 
+#ifdef OPENSSL_FIPS
+DH *	FIPS_dh_new(void);
+void	FIPS_dh_free(DH *dh);
+#endif
+
 void DH_set_default_method(const DH_METHOD *meth);
 const DH_METHOD *DH_get_default_method(void);
 int DH_set_method(DH *dh, const DH_METHOD *meth);
@@ -218,6 +225,9 @@
 #define DH_F_DHPARAMS_PRINT				 100
 #define DH_F_DHPARAMS_PRINT_FP				 101
 #define DH_F_DH_BUILTIN_GENPARAMS			 106
+#define DH_F_DH_COMPUTE_KEY				 107
+#define DH_F_DH_GENERATE_KEY				 108
+#define DH_F_DH_GENERATE_PARAMETERS			 109
 #define DH_F_DH_NEW_METHOD				 105
 #define DH_F_GENERATE_KEY				 103
 #define DH_F_GENERATE_PARAMETERS			 104
@@ -225,6 +235,7 @@
 /* Reason codes. */
 #define DH_R_BAD_GENERATOR				 101
 #define DH_R_INVALID_PUBKEY				 102
+#define DH_R_KEY_SIZE_TOO_SMALL				 104
 #define DH_R_MODULUS_TOO_LARGE				 103
 #define DH_R_NO_PRIVATE_VALUE				 100
 
diff --git a/crypto/dh/dh_asn1.c b/crypto/dh/dh_asn1.c
index 769b5b6..76740af 100644
--- a/crypto/dh/dh_asn1.c
+++ b/crypto/dh/dh_asn1.c
@@ -1,5 +1,5 @@
 /* dh_asn1.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c
index b846913..316cb92 100644
--- a/crypto/dh/dh_check.c
+++ b/crypto/dh/dh_check.c
@@ -70,6 +70,8 @@
  * should hold.
  */
 
+#ifndef OPENSSL_FIPS
+
 int DH_check(const DH *dh, int *ret)
 	{
 	int ok=0;
@@ -140,3 +142,5 @@
 	if (q != NULL) BN_free(q);
 	return(ok);
 	}
+
+#endif
diff --git a/crypto/dh/dh_err.c b/crypto/dh/dh_err.c
index a2d8196..13263c8 100644
--- a/crypto/dh/dh_err.c
+++ b/crypto/dh/dh_err.c
@@ -1,6 +1,6 @@
 /* crypto/dh/dh_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2007 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
@@ -74,6 +74,9 @@
 {ERR_FUNC(DH_F_DHPARAMS_PRINT),	"DHparams_print"},
 {ERR_FUNC(DH_F_DHPARAMS_PRINT_FP),	"DHparams_print_fp"},
 {ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS),	"DH_BUILTIN_GENPARAMS"},
+{ERR_FUNC(DH_F_DH_COMPUTE_KEY),	"DH_compute_key"},
+{ERR_FUNC(DH_F_DH_GENERATE_KEY),	"DH_generate_key"},
+{ERR_FUNC(DH_F_DH_GENERATE_PARAMETERS),	"DH_generate_parameters"},
 {ERR_FUNC(DH_F_DH_NEW_METHOD),	"DH_new_method"},
 {ERR_FUNC(DH_F_GENERATE_KEY),	"GENERATE_KEY"},
 {ERR_FUNC(DH_F_GENERATE_PARAMETERS),	"GENERATE_PARAMETERS"},
@@ -84,6 +87,7 @@
 	{
 {ERR_REASON(DH_R_BAD_GENERATOR)          ,"bad generator"},
 {ERR_REASON(DH_R_INVALID_PUBKEY)         ,"invalid public key"},
+{ERR_REASON(DH_R_KEY_SIZE_TOO_SMALL)     ,"key size too small"},
 {ERR_REASON(DH_R_MODULUS_TOO_LARGE)      ,"modulus too large"},
 {ERR_REASON(DH_R_NO_PRIVATE_VALUE)       ,"no private value"},
 {0,NULL}
diff --git a/crypto/dh/dh_gen.c b/crypto/dh/dh_gen.c
index cfd5b11..999e1de 100644
--- a/crypto/dh/dh_gen.c
+++ b/crypto/dh/dh_gen.c
@@ -66,6 +66,8 @@
 #include <openssl/bn.h>
 #include <openssl/dh.h>
 
+#ifndef OPENSSL_FIPS
+
 static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb);
 
 int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, BN_GENCB *cb)
@@ -173,3 +175,5 @@
 		}
 	return ok;
 	}
+
+#endif
diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c
index e7db440..79dd331 100644
--- a/crypto/dh/dh_key.c
+++ b/crypto/dh/dh_key.c
@@ -62,6 +62,8 @@
 #include <openssl/rand.h>
 #include <openssl/dh.h>
 
+#ifndef OPENSSL_FIPS
+
 static int generate_key(DH *dh);
 static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
 static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
@@ -261,3 +263,5 @@
 		BN_MONT_CTX_free(dh->method_mont_p);
 	return(1);
 	}
+
+#endif
diff --git a/crypto/dsa/Makefile b/crypto/dsa/Makefile
index 676baf7..2cc45cd 100644
--- a/crypto/dsa/Makefile
+++ b/crypto/dsa/Makefile
@@ -18,9 +18,9 @@
 
 LIB=$(TOP)/libcrypto.a
 LIBSRC= dsa_gen.c dsa_key.c dsa_lib.c dsa_asn1.c dsa_vrf.c dsa_sign.c \
-	dsa_err.c dsa_ossl.c dsa_depr.c
+	dsa_err.c dsa_ossl.c dsa_depr.c dsa_utl.c
 LIBOBJ= dsa_gen.o dsa_key.o dsa_lib.o dsa_asn1.o dsa_vrf.o dsa_sign.o \
-	dsa_err.o dsa_ossl.o dsa_depr.o
+	dsa_err.o dsa_ossl.o dsa_depr.o dsa_utl.o
 
 SRC= $(LIBSRC)
 
@@ -35,7 +35,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -78,9 +78,10 @@
 
 dsa_asn1.o: ../../e_os.h ../../include/openssl/asn1.h
 dsa_asn1.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
-dsa_asn1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-dsa_asn1.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
-dsa_asn1.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+dsa_asn1.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+dsa_asn1.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
+dsa_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+dsa_asn1.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
 dsa_asn1.o: ../../include/openssl/opensslconf.h
 dsa_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 dsa_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
@@ -90,8 +91,9 @@
 dsa_depr.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 dsa_depr.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
 dsa_depr.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-dsa_depr.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-dsa_depr.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+dsa_depr.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+dsa_depr.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+dsa_depr.o: ../../include/openssl/opensslconf.h
 dsa_depr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 dsa_depr.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
 dsa_depr.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -108,12 +110,13 @@
 dsa_gen.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 dsa_gen.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
 dsa_gen.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-dsa_gen.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-dsa_gen.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-dsa_gen.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-dsa_gen.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-dsa_gen.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-dsa_gen.o: ../../include/openssl/symhacks.h ../cryptlib.h dsa_gen.c
+dsa_gen.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+dsa_gen.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+dsa_gen.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+dsa_gen.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+dsa_gen.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+dsa_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dsa_gen.o: ../cryptlib.h dsa_gen.c
 dsa_key.o: ../../e_os.h ../../include/openssl/bio.h ../../include/openssl/bn.h
 dsa_key.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 dsa_key.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
@@ -126,12 +129,17 @@
 dsa_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 dsa_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 dsa_lib.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
-dsa_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-dsa_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-dsa_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-dsa_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-dsa_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-dsa_lib.o: ../cryptlib.h dsa_lib.c
+dsa_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+dsa_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+dsa_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+dsa_lib.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+dsa_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+dsa_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+dsa_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dsa_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+dsa_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dsa_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+dsa_lib.o: ../../include/openssl/x509_vfy.h ../cryptlib.h dsa_lib.c
 dsa_ossl.o: ../../e_os.h ../../include/openssl/asn1.h
 dsa_ossl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 dsa_ossl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
@@ -146,19 +154,34 @@
 dsa_sign.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 dsa_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 dsa_sign.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
-dsa_sign.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-dsa_sign.o: ../../include/openssl/opensslconf.h
+dsa_sign.o: ../../include/openssl/err.h ../../include/openssl/fips.h
+dsa_sign.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
 dsa_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 dsa_sign.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
 dsa_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 dsa_sign.o: ../cryptlib.h dsa_sign.c
+dsa_utl.o: ../../e_os.h ../../include/openssl/asn1.h
+dsa_utl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+dsa_utl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+dsa_utl.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
+dsa_utl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+dsa_utl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+dsa_utl.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+dsa_utl.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+dsa_utl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+dsa_utl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+dsa_utl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+dsa_utl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+dsa_utl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+dsa_utl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+dsa_utl.o: ../../include/openssl/x509_vfy.h ../cryptlib.h dsa_utl.c
 dsa_vrf.o: ../../e_os.h ../../include/openssl/asn1.h
 dsa_vrf.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
 dsa_vrf.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
 dsa_vrf.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
 dsa_vrf.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-dsa_vrf.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-dsa_vrf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-dsa_vrf.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-dsa_vrf.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-dsa_vrf.o: ../cryptlib.h dsa_vrf.c
+dsa_vrf.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+dsa_vrf.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+dsa_vrf.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+dsa_vrf.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+dsa_vrf.o: ../../include/openssl/symhacks.h ../cryptlib.h dsa_vrf.c
diff --git a/crypto/dsa/dsa.h b/crypto/dsa/dsa.h
index 3a8fe5b..702c50d 100644
--- a/crypto/dsa/dsa.h
+++ b/crypto/dsa/dsa.h
@@ -88,6 +88,8 @@
 # define OPENSSL_DSA_MAX_MODULUS_BITS	10000
 #endif
 
+#define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024
+
 #define DSA_FLAG_CACHE_MONT_P	0x01
 #define DSA_FLAG_NO_EXP_CONSTTIME       0x02 /* new with 0.9.7h; the built-in DSA
                                               * implementation now uses constant time
@@ -97,6 +99,25 @@
                                               * be used for all exponents.
                                               */
 
+/* If this flag is set the DSA method is FIPS compliant and can be used
+ * in FIPS mode. This is set in the validated module method. If an
+ * application sets this flag in its own methods it is its reposibility
+ * to ensure the result is compliant.
+ */
+
+#define DSA_FLAG_FIPS_METHOD			0x0400
+
+/* If this flag is set the operations normally disabled in FIPS mode are
+ * permitted it is then the applications responsibility to ensure that the
+ * usage is compliant.
+ */
+
+#define DSA_FLAG_NON_FIPS_ALLOW			0x0400
+
+#ifdef OPENSSL_FIPS
+#define FIPS_DSA_SIZE_T	int
+#endif
+
 #ifdef  __cplusplus
 extern "C" {
 #endif
@@ -189,6 +210,11 @@
 const DSA_METHOD *DSA_get_default_method(void);
 int	DSA_set_method(DSA *dsa, const DSA_METHOD *);
 
+#ifdef OPENSSL_FIPS
+DSA *	FIPS_dsa_new(void);
+void	FIPS_dsa_free (DSA *r);
+#endif
+
 DSA *	DSA_new(void);
 DSA *	DSA_new_method(ENGINE *engine);
 void	DSA_free (DSA *r);
@@ -249,6 +275,11 @@
 DH *DSA_dup_DH(const DSA *r);
 #endif
 
+#ifdef OPENSSL_FIPS
+int FIPS_dsa_sig_encode(unsigned char *out, DSA_SIG *sig);
+int FIPS_dsa_sig_decode(DSA_SIG *sig, const unsigned char *in, int inlen);
+#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.
@@ -261,11 +292,16 @@
 #define DSA_F_D2I_DSA_SIG				 110
 #define DSA_F_DSAPARAMS_PRINT				 100
 #define DSA_F_DSAPARAMS_PRINT_FP			 101
+#define DSA_F_DSA_BUILTIN_KEYGEN			 119
+#define DSA_F_DSA_BUILTIN_PARAMGEN			 118
 #define DSA_F_DSA_DO_SIGN				 112
 #define DSA_F_DSA_DO_VERIFY				 113
+#define DSA_F_DSA_GENERATE_PARAMETERS			 117
 #define DSA_F_DSA_NEW_METHOD				 103
 #define DSA_F_DSA_PRINT					 104
 #define DSA_F_DSA_PRINT_FP				 105
+#define DSA_F_DSA_SET_DEFAULT_METHOD			 115
+#define DSA_F_DSA_SET_METHOD				 116
 #define DSA_F_DSA_SIGN					 106
 #define DSA_F_DSA_SIGN_SETUP				 107
 #define DSA_F_DSA_SIG_NEW				 109
@@ -276,8 +312,11 @@
 /* Reason codes. */
 #define DSA_R_BAD_Q_VALUE				 102
 #define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE		 100
+#define DSA_R_KEY_SIZE_TOO_SMALL			 106
 #define DSA_R_MISSING_PARAMETERS			 101
 #define DSA_R_MODULUS_TOO_LARGE				 103
+#define DSA_R_NON_FIPS_METHOD				 104
+#define DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE	 105
 
 #ifdef  __cplusplus
 }
diff --git a/crypto/dsa/dsa_asn1.c b/crypto/dsa/dsa_asn1.c
index 23fce55..0645fac 100644
--- a/crypto/dsa/dsa_asn1.c
+++ b/crypto/dsa/dsa_asn1.c
@@ -1,5 +1,5 @@
 /* dsa_asn1.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
@@ -61,6 +61,11 @@
 #include <openssl/dsa.h>
 #include <openssl/asn1.h>
 #include <openssl/asn1t.h>
+#include <openssl/bn.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 
 /* Override the default new methods */
 static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
@@ -83,7 +88,7 @@
 	ASN1_SIMPLE(DSA_SIG, s, CBIGNUM)
 } ASN1_SEQUENCE_END_cb(DSA_SIG, DSA_SIG)
 
-IMPLEMENT_ASN1_FUNCTIONS_const(DSA_SIG)
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG,DSA_SIG,DSA_SIG)
 
 /* Override the default free and new methods */
 static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
@@ -138,3 +143,76 @@
 } ASN1_CHOICE_END_cb(DSA, DSAPublicKey, write_params)
 
 IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey)
+
+int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
+	     unsigned int *siglen, DSA *dsa)
+	{
+	DSA_SIG *s;
+#ifdef OPENSSL_FIPS
+	if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
+		{
+		DSAerr(DSA_F_DSA_SIGN, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+		return 0;
+		}
+#endif
+	s=DSA_do_sign(dgst,dlen,dsa);
+	if (s == NULL)
+		{
+		*siglen=0;
+		return(0);
+		}
+	*siglen=i2d_DSA_SIG(s,&sig);
+	DSA_SIG_free(s);
+	return(1);
+	}
+
+int DSA_size(const DSA *r)
+	{
+	int ret,i;
+	ASN1_INTEGER bs;
+	unsigned char buf[4];	/* 4 bytes looks really small.
+				   However, i2d_ASN1_INTEGER() will not look
+				   beyond the first byte, as long as the second
+				   parameter is NULL. */
+
+	i=BN_num_bits(r->q);
+	bs.length=(i+7)/8;
+	bs.data=buf;
+	bs.type=V_ASN1_INTEGER;
+	/* If the top bit is set the asn1 encoding is 1 larger. */
+	buf[0]=0xff;	
+
+	i=i2d_ASN1_INTEGER(&bs,NULL);
+	i+=i; /* r and s */
+	ret=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
+	return(ret);
+	}
+
+/* data has already been hashed (probably with SHA or SHA-1). */
+/* returns
+ *      1: correct signature
+ *      0: incorrect signature
+ *     -1: error
+ */
+int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
+	     const unsigned char *sigbuf, int siglen, DSA *dsa)
+	{
+	DSA_SIG *s;
+	int ret=-1;
+#ifdef OPENSSL_FIPS
+	if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
+		{
+		DSAerr(DSA_F_DSA_VERIFY, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+		return 0;
+		}
+#endif
+
+	s = DSA_SIG_new();
+	if (s == NULL) return(ret);
+	if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err;
+	ret=DSA_do_verify(dgst,dgst_len,s,dsa);
+err:
+	DSA_SIG_free(s);
+	return(ret);
+	}
+
diff --git a/crypto/dsa/dsa_err.c b/crypto/dsa/dsa_err.c
index 7687119..872839a 100644
--- a/crypto/dsa/dsa_err.c
+++ b/crypto/dsa/dsa_err.c
@@ -1,6 +1,6 @@
 /* crypto/dsa/dsa_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2007 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
@@ -73,11 +73,16 @@
 {ERR_FUNC(DSA_F_D2I_DSA_SIG),	"d2i_DSA_SIG"},
 {ERR_FUNC(DSA_F_DSAPARAMS_PRINT),	"DSAparams_print"},
 {ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP),	"DSAparams_print_fp"},
+{ERR_FUNC(DSA_F_DSA_BUILTIN_KEYGEN),	"DSA_BUILTIN_KEYGEN"},
+{ERR_FUNC(DSA_F_DSA_BUILTIN_PARAMGEN),	"DSA_BUILTIN_PARAMGEN"},
 {ERR_FUNC(DSA_F_DSA_DO_SIGN),	"DSA_do_sign"},
 {ERR_FUNC(DSA_F_DSA_DO_VERIFY),	"DSA_do_verify"},
+{ERR_FUNC(DSA_F_DSA_GENERATE_PARAMETERS),	"DSA_generate_parameters"},
 {ERR_FUNC(DSA_F_DSA_NEW_METHOD),	"DSA_new_method"},
 {ERR_FUNC(DSA_F_DSA_PRINT),	"DSA_print"},
 {ERR_FUNC(DSA_F_DSA_PRINT_FP),	"DSA_print_fp"},
+{ERR_FUNC(DSA_F_DSA_SET_DEFAULT_METHOD),	"DSA_set_default_method"},
+{ERR_FUNC(DSA_F_DSA_SET_METHOD),	"DSA_set_method"},
 {ERR_FUNC(DSA_F_DSA_SIGN),	"DSA_sign"},
 {ERR_FUNC(DSA_F_DSA_SIGN_SETUP),	"DSA_sign_setup"},
 {ERR_FUNC(DSA_F_DSA_SIG_NEW),	"DSA_SIG_new"},
@@ -91,8 +96,11 @@
 	{
 {ERR_REASON(DSA_R_BAD_Q_VALUE)           ,"bad q value"},
 {ERR_REASON(DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"},
+{ERR_REASON(DSA_R_KEY_SIZE_TOO_SMALL)    ,"key size too small"},
 {ERR_REASON(DSA_R_MISSING_PARAMETERS)    ,"missing parameters"},
 {ERR_REASON(DSA_R_MODULUS_TOO_LARGE)     ,"modulus too large"},
+{ERR_REASON(DSA_R_NON_FIPS_METHOD)       ,"non fips method"},
+{ERR_REASON(DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE),"operation not allowed in fips mode"},
 {0,NULL}
 	};
 
diff --git a/crypto/dsa/dsa_gen.c b/crypto/dsa/dsa_gen.c
index ca0b86a..6f1728e 100644
--- a/crypto/dsa/dsa_gen.c
+++ b/crypto/dsa/dsa_gen.c
@@ -82,6 +82,8 @@
 #include <openssl/rand.h>
 #include <openssl/sha.h>
 
+#ifndef OPENSSL_FIPS
+
 static int dsa_builtin_paramgen(DSA *ret, int bits,
 		unsigned char *seed_in, int seed_len,
 		int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
@@ -320,3 +322,4 @@
 	return ok;
 	}
 #endif
+#endif
diff --git a/crypto/dsa/dsa_key.c b/crypto/dsa/dsa_key.c
index c4aa86b..5e39124 100644
--- a/crypto/dsa/dsa_key.c
+++ b/crypto/dsa/dsa_key.c
@@ -64,6 +64,8 @@
 #include <openssl/dsa.h>
 #include <openssl/rand.h>
 
+#ifndef OPENSSL_FIPS
+
 static int dsa_builtin_keygen(DSA *dsa);
 
 int DSA_generate_key(DSA *dsa)
@@ -126,3 +128,5 @@
 	return(ok);
 	}
 #endif
+
+#endif
diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c
index e9b7590..7ac9dc8 100644
--- a/crypto/dsa/dsa_lib.c
+++ b/crypto/dsa/dsa_lib.c
@@ -76,6 +76,14 @@
 
 void DSA_set_default_method(const DSA_METHOD *meth)
 	{
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode() && !(meth->flags & DSA_FLAG_FIPS_METHOD))
+		{
+		DSAerr(DSA_F_DSA_SET_DEFAULT_METHOD, DSA_R_NON_FIPS_METHOD);
+		return;
+		}
+#endif
+		
 	default_DSA_method = meth;
 	}
 
@@ -96,6 +104,13 @@
 	/* NB: The caller is specifically setting a method, so it's not up to us
 	 * to deal with which ENGINE it comes from. */
         const DSA_METHOD *mtmp;
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode() && !(meth->flags & DSA_FLAG_FIPS_METHOD))
+		{
+		DSAerr(DSA_F_DSA_SET_METHOD, DSA_R_NON_FIPS_METHOD);
+		return 0;
+		}
+#endif
         mtmp = dsa->meth;
         if (mtmp->finish) mtmp->finish(dsa);
 #ifndef OPENSSL_NO_ENGINE
@@ -147,6 +162,18 @@
 			}
 		}
 #endif
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode() && !(ret->meth->flags & DSA_FLAG_FIPS_METHOD))
+		{
+		DSAerr(DSA_F_DSA_NEW_METHOD, DSA_R_NON_FIPS_METHOD);
+#ifndef OPENSSL_NO_ENGINE
+		if (ret->engine)
+			ENGINE_finish(ret->engine);
+#endif
+		OPENSSL_free(ret);
+		return NULL;
+		}
+#endif
 
 	ret->pad=0;
 	ret->version=0;
@@ -233,28 +260,6 @@
 	return ((i > 1) ? 1 : 0);
 	}
 
-int DSA_size(const DSA *r)
-	{
-	int ret,i;
-	ASN1_INTEGER bs;
-	unsigned char buf[4];	/* 4 bytes looks really small.
-				   However, i2d_ASN1_INTEGER() will not look
-				   beyond the first byte, as long as the second
-				   parameter is NULL. */
-
-	i=BN_num_bits(r->q);
-	bs.length=(i+7)/8;
-	bs.data=buf;
-	bs.type=V_ASN1_INTEGER;
-	/* If the top bit is set the asn1 encoding is 1 larger. */
-	buf[0]=0xff;	
-
-	i=i2d_ASN1_INTEGER(&bs,NULL);
-	i+=i; /* r and s */
-	ret=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
-	return(ret);
-	}
-
 int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
 	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
         {
diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c
index 75ff7cc..412cf1d 100644
--- a/crypto/dsa/dsa_ossl.c
+++ b/crypto/dsa/dsa_ossl.c
@@ -65,6 +65,8 @@
 #include <openssl/rand.h>
 #include <openssl/asn1.h>
 
+#ifndef OPENSSL_FIPS
+
 static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa);
 static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
 static int dsa_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
@@ -391,3 +393,4 @@
 	return(1);
 }
 
+#endif
diff --git a/crypto/dsa/dsa_sign.c b/crypto/dsa/dsa_sign.c
index 8920502..4cfbbe5 100644
--- a/crypto/dsa/dsa_sign.c
+++ b/crypto/dsa/dsa_sign.c
@@ -64,29 +64,32 @@
 #include <openssl/dsa.h>
 #include <openssl/rand.h>
 #include <openssl/asn1.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 
 DSA_SIG * DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
 	{
-	return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
-	}
-
-int DSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig,
-	     unsigned int *siglen, DSA *dsa)
-	{
-	DSA_SIG *s;
-	s=DSA_do_sign(dgst,dlen,dsa);
-	if (s == NULL)
+#ifdef OPENSSL_FIPS
+	if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
 		{
-		*siglen=0;
-		return(0);
+		DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+		return NULL;
 		}
-	*siglen=i2d_DSA_SIG(s,&sig);
-	DSA_SIG_free(s);
-	return(1);
+#endif
+	return dsa->meth->dsa_do_sign(dgst, dlen, dsa);
 	}
 
 int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
 	{
+#ifdef OPENSSL_FIPS
+	if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
+		{
+		DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+		return 0;
+		}
+#endif
 	return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp);
 	}
 
diff --git a/crypto/dsa/dsa_utl.c b/crypto/dsa/dsa_utl.c
new file mode 100644
index 0000000..24c021d
--- /dev/null
+++ b/crypto/dsa/dsa_utl.c
@@ -0,0 +1,95 @@
+/* crypto/dsa/dsa_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/asn1.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+
+DSA_SIG *DSA_SIG_new(void)
+	{
+	DSA_SIG *sig;
+	sig = OPENSSL_malloc(sizeof(DSA_SIG));
+	if (!sig)
+		return NULL;
+	sig->r = NULL;
+	sig->s = NULL;
+	return sig;
+	}
+
+void DSA_SIG_free(DSA_SIG *sig)
+	{
+	if (sig)
+		{
+		if (sig->r)
+			BN_free(sig->r);
+		if (sig->s)
+			BN_free(sig->s);
+		OPENSSL_free(sig);
+		}
+	}
+
diff --git a/crypto/dsa/dsa_vrf.c b/crypto/dsa/dsa_vrf.c
index c4aeddd..c75e423 100644
--- a/crypto/dsa/dsa_vrf.c
+++ b/crypto/dsa/dsa_vrf.c
@@ -64,31 +64,21 @@
 #include <openssl/dsa.h>
 #include <openssl/rand.h>
 #include <openssl/asn1.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 #include <openssl/asn1_mac.h>
 
 int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig,
 		  DSA *dsa)
 	{
+#ifdef OPENSSL_FIPS
+	if(FIPS_mode() && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW))
+		{
+		DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+		return 0;
+		}
+#endif
 	return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa);
 	}
-
-/* data has already been hashed (probably with SHA or SHA-1). */
-/* returns
- *      1: correct signature
- *      0: incorrect signature
- *     -1: error
- */
-int DSA_verify(int type, const unsigned char *dgst, int dgst_len,
-	     const unsigned char *sigbuf, int siglen, DSA *dsa)
-	{
-	DSA_SIG *s;
-	int ret=-1;
-
-	s = DSA_SIG_new();
-	if (s == NULL) return(ret);
-	if (d2i_DSA_SIG(&s,&sigbuf,siglen) == NULL) goto err;
-	ret=DSA_do_verify(dgst,dgst_len,s,dsa);
-err:
-	DSA_SIG_free(s);
-	return(ret);
-	}
diff --git a/crypto/dso/Makefile b/crypto/dso/Makefile
index 07f5d8d..52f1528 100644
--- a/crypto/dso/Makefile
+++ b/crypto/dso/Makefile
@@ -35,7 +35,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
diff --git a/crypto/dyn_lck.c b/crypto/dyn_lck.c
new file mode 100644
index 0000000..7f82c41
--- /dev/null
+++ b/crypto/dyn_lck.c
@@ -0,0 +1,428 @@
+/* crypto/cryptlib.c */
+/* ====================================================================
+ * Copyright (c) 1998-2003 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).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#include "cryptlib.h"
+#include <openssl/safestack.h>
+
+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
+static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */
+#endif
+
+DECLARE_STACK_OF(CRYPTO_dynlock)
+IMPLEMENT_STACK_OF(CRYPTO_dynlock)
+
+/* real #defines in crypto.h, keep these upto date */
+static const char* const lock_names[CRYPTO_NUM_LOCKS] =
+	{
+	"<<ERROR>>",
+	"err",
+	"ex_data",
+	"x509",
+	"x509_info",
+	"x509_pkey",
+	"x509_crl",
+	"x509_req",
+	"dsa",
+	"rsa",
+	"evp_pkey",
+	"x509_store",
+	"ssl_ctx",
+	"ssl_cert",
+	"ssl_session",
+	"ssl_sess_cert",
+	"ssl",
+	"ssl_method",
+	"rand",
+	"rand2",
+	"debug_malloc",
+	"BIO",
+	"gethostbyname",
+	"getservbyname",
+	"readdir",
+	"RSA_blinding",
+	"dh",
+	"debug_malloc2",
+	"dso",
+	"dynlock",
+	"engine",
+	"ui",
+	"ecdsa",
+	"ec",
+	"ecdh",
+	"bn",
+	"ec_pre_comp",
+	"store",
+	"comp",
+#ifndef OPENSSL_FIPS
+# if CRYPTO_NUM_LOCKS != 39
+#  error "Inconsistency between crypto.h and cryptlib.c"
+# endif
+#else
+	"fips",
+	"fips2",
+# if CRYPTO_NUM_LOCKS != 41
+#  error "Inconsistency between crypto.h and cryptlib.c"
+# endif
+#endif
+	};
+
+/* This is for applications to allocate new type names in the non-dynamic
+   array of lock names.  These are numbered with positive numbers.  */
+static STACK *app_locks=NULL;
+
+/* For applications that want a more dynamic way of handling threads, the
+   following stack is used.  These are externally numbered with negative
+   numbers.  */
+static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL;
+
+
+static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
+	(const char *file,int line)=NULL;
+static void (MS_FAR *dynlock_lock_callback)(int mode,
+	struct CRYPTO_dynlock_value *l, const char *file,int line)=NULL;
+static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l,
+	const char *file,int line)=NULL;
+
+int CRYPTO_get_new_lockid(char *name)
+	{
+	char *str;
+	int i;
+
+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
+	/* A hack to make Visual C++ 5.0 work correctly when linking as
+	 * a DLL using /MT. Without this, the application cannot use
+	 * and floating point printf's.
+	 * It also seems to be needed for Visual C 1.5 (win16) */
+	SSLeay_MSVC5_hack=(double)name[0]*(double)name[1];
+#endif
+
+	if ((app_locks == NULL) && ((app_locks=sk_new_null()) == NULL))
+		{
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	if ((str=BUF_strdup(name)) == NULL)
+		{
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	i=sk_push(app_locks,str);
+	if (!i)
+		OPENSSL_free(str);
+	else
+		i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */
+	return(i);
+	}
+
+int CRYPTO_get_new_dynlockid(void)
+	{
+	int i = 0;
+	CRYPTO_dynlock *pointer = NULL;
+
+	if (dynlock_create_callback == NULL)
+		{
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
+		return(0);
+		}
+	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
+	if ((dyn_locks == NULL)
+		&& ((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL))
+		{
+		CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+
+	pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock));
+	if (pointer == NULL)
+		{
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	pointer->references = 1;
+	pointer->data = dynlock_create_callback(__FILE__,__LINE__);
+	if (pointer->data == NULL)
+		{
+		OPENSSL_free(pointer);
+		CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+
+	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
+	/* First, try to find an existing empty slot */
+	i=sk_CRYPTO_dynlock_find(dyn_locks,NULL);
+	/* If there was none, push, thereby creating a new one */
+	if (i == -1)
+		/* Since sk_push() returns the number of items on the
+		   stack, not the location of the pushed item, we need
+		   to transform the returned number into a position,
+		   by decreasing it.  */
+		i=sk_CRYPTO_dynlock_push(dyn_locks,pointer) - 1;
+	else
+		/* If we found a place with a NULL pointer, put our pointer
+		   in it.  */
+		(void)sk_CRYPTO_dynlock_set(dyn_locks,i,pointer);
+	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+
+	if (i == -1)
+		{
+		dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
+		OPENSSL_free(pointer);
+		}
+	else
+		i += 1; /* to avoid 0 */
+	return -i;
+	}
+
+void CRYPTO_destroy_dynlockid(int i)
+	{
+	CRYPTO_dynlock *pointer = NULL;
+	if (i)
+		i = -i-1;
+	if (dynlock_destroy_callback == NULL)
+		return;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
+
+	if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks))
+		{
+		CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+		return;
+		}
+	pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
+	if (pointer != NULL)
+		{
+		--pointer->references;
+#ifdef REF_CHECK
+		if (pointer->references < 0)
+			{
+			fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference count\n");
+			abort();
+			}
+		else
+#endif
+			if (pointer->references <= 0)
+				{
+				(void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
+				}
+			else
+				pointer = NULL;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+
+	if (pointer)
+		{
+		dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
+		OPENSSL_free(pointer);
+		}
+	}
+
+struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i)
+	{
+	CRYPTO_dynlock *pointer = NULL;
+	if (i)
+		i = -i-1;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
+
+	if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
+		pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
+	if (pointer)
+		pointer->references++;
+
+	CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
+
+	if (pointer)
+		return pointer->data;
+	return NULL;
+	}
+
+struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))
+	(const char *file,int line)
+	{
+	return(dynlock_create_callback);
+	}
+
+void (*CRYPTO_get_dynlock_lock_callback(void))(int mode,
+	struct CRYPTO_dynlock_value *l, const char *file,int line)
+	{
+	return(dynlock_lock_callback);
+	}
+
+void (*CRYPTO_get_dynlock_destroy_callback(void))
+	(struct CRYPTO_dynlock_value *l, const char *file,int line)
+	{
+	return(dynlock_destroy_callback);
+	}
+
+void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
+	(const char *file, int line))
+	{
+	dynlock_create_callback=func;
+	}
+
+static void do_dynlock(int mode, int type, const char *file, int line)
+	{
+	if (dynlock_lock_callback != NULL)
+		{
+		struct CRYPTO_dynlock_value *pointer
+				= CRYPTO_get_dynlock_value(type);
+
+		OPENSSL_assert(pointer != NULL);
+
+		dynlock_lock_callback(mode, pointer, file, line);
+
+		CRYPTO_destroy_dynlockid(type);
+		}
+	}
+
+void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode,
+	struct CRYPTO_dynlock_value *l, const char *file, int line))
+	{
+	/* Set callback so CRYPTO_lock() can now handle dynamic locks.
+	 * This is OK because at this point and application shouldn't be using
+	 * OpenSSL from multiple threads because it is setting up the locking
+	 * callbacks.
+	 */
+	static int done = 0;
+	if (!done)
+		{
+		int_CRYPTO_set_do_dynlock_callback(do_dynlock);
+		done = 1;
+		}
+		
+	dynlock_lock_callback=func;
+	}
+
+void CRYPTO_set_dynlock_destroy_callback(void (*func)
+	(struct CRYPTO_dynlock_value *l, const char *file, int line))
+	{
+	dynlock_destroy_callback=func;
+	}
+
+const char *CRYPTO_get_lock_name(int type)
+	{
+	if (type < 0)
+		return("dynamic");
+	else if (type < CRYPTO_NUM_LOCKS)
+		return(lock_names[type]);
+	else if (type-CRYPTO_NUM_LOCKS > sk_num(app_locks))
+		return("ERROR");
+	else
+		return(sk_value(app_locks,type-CRYPTO_NUM_LOCKS));
+	}
+
diff --git a/crypto/ec/Makefile b/crypto/ec/Makefile
index 42f7bb7..b5bbc9f 100644
--- a/crypto/ec/Makefile
+++ b/crypto/ec/Makefile
@@ -38,7 +38,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c
index 3d6c900..12fb0e6 100644
--- a/crypto/ec/ec_key.c
+++ b/crypto/ec/ec_key.c
@@ -296,7 +296,7 @@
 	{
 	int	ok   = 0;
 	BN_CTX	*ctx = NULL;
-	BIGNUM	*order  = NULL;
+	const BIGNUM	*order  = NULL;
 	EC_POINT *point = NULL;
 
 	if (!eckey || !eckey->group || !eckey->pub_key)
@@ -307,8 +307,6 @@
 	
 	if ((ctx = BN_CTX_new()) == NULL)
 		goto err;
-	if ((order = BN_new()) == NULL)
-		goto err;
 	if ((point = EC_POINT_new(eckey->group)) == NULL)
 		goto err;
 
@@ -319,17 +317,13 @@
 		goto err;
 		}
 	/* testing whether pub_key * order is the point at infinity */
-	if (!EC_GROUP_get_order(eckey->group, order, ctx))
+	order = &eckey->group->order;
+	if (BN_is_zero(order))
 		{
 		ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
 		goto err;
 		}
-	if (!EC_POINT_copy(point, eckey->pub_key))
-		{
-		ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
-		goto err;
-		}
-	if (!EC_POINT_mul(eckey->group, point, order, NULL, NULL, ctx))
+	if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx))
 		{
 		ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB);
 		goto err;
@@ -366,8 +360,6 @@
 err:
 	if (ctx   != NULL)
 		BN_CTX_free(ctx);
-	if (order != NULL)
-		BN_free(order);
 	if (point != NULL)
 		EC_POINT_free(point);
 	return(ok);
diff --git a/crypto/ecdh/Makefile b/crypto/ecdh/Makefile
index 95aa69f..7a7b618 100644
--- a/crypto/ecdh/Makefile
+++ b/crypto/ecdh/Makefile
@@ -34,7 +34,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -84,20 +84,31 @@
 ech_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 ech_err.o: ech_err.c
 ech_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ech_key.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-ech_key.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
-ech_key.o: ../../include/openssl/engine.h ../../include/openssl/opensslconf.h
-ech_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ech_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ech_key.o: ../../include/openssl/symhacks.h ech_key.c ech_locl.h
+ech_key.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+ech_key.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ech_key.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ech_key.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
+ech_key.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+ech_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+ech_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+ech_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+ech_key.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+ech_key.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ech_key.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+ech_key.o: ech_key.c ech_locl.h
 ech_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ech_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-ech_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+ech_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+ech_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ech_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 ech_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
-ech_lib.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+ech_lib.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+ech_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ech_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 ech_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ech_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ech_lib.o: ../../include/openssl/symhacks.h ech_lib.c ech_locl.h
+ech_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+ech_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ech_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+ech_lib.o: ../../include/openssl/x509_vfy.h ech_lib.c ech_locl.h
 ech_ossl.o: ../../e_os.h ../../include/openssl/asn1.h
 ech_ossl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 ech_ossl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
diff --git a/crypto/ecdsa/Makefile b/crypto/ecdsa/Makefile
index 16a93cd..4865f3c 100644
--- a/crypto/ecdsa/Makefile
+++ b/crypto/ecdsa/Makefile
@@ -34,7 +34,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -92,13 +92,18 @@
 ecs_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 ecs_err.o: ecs_err.c
 ecs_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ecs_lib.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-ecs_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ecs_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+ecs_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+ecs_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 ecs_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
-ecs_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ecs_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+ecs_lib.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+ecs_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 ecs_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-ecs_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+ecs_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+ecs_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 ecs_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ecs_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
 ecs_lib.o: ecs_lib.c ecs_locl.h
 ecs_ossl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 ecs_ossl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
@@ -110,16 +115,28 @@
 ecs_ossl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 ecs_ossl.o: ../../include/openssl/symhacks.h ecs_locl.h ecs_ossl.c
 ecs_sign.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ecs_sign.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-ecs_sign.o: ../../include/openssl/ec.h ../../include/openssl/ecdsa.h
-ecs_sign.o: ../../include/openssl/engine.h ../../include/openssl/opensslconf.h
+ecs_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+ecs_sign.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ecs_sign.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ecs_sign.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
+ecs_sign.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+ecs_sign.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+ecs_sign.o: ../../include/openssl/opensslconf.h
 ecs_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ecs_sign.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ecs_sign.o: ../../include/openssl/symhacks.h ecs_locl.h ecs_sign.c
+ecs_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+ecs_sign.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+ecs_sign.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+ecs_sign.o: ../../include/openssl/x509_vfy.h ecs_locl.h ecs_sign.c
 ecs_vrf.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ecs_vrf.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-ecs_vrf.o: ../../include/openssl/ec.h ../../include/openssl/ecdsa.h
-ecs_vrf.o: ../../include/openssl/engine.h ../../include/openssl/opensslconf.h
-ecs_vrf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-ecs_vrf.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-ecs_vrf.o: ../../include/openssl/symhacks.h ecs_locl.h ecs_vrf.c
+ecs_vrf.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+ecs_vrf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ecs_vrf.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ecs_vrf.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
+ecs_vrf.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+ecs_vrf.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+ecs_vrf.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+ecs_vrf.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+ecs_vrf.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+ecs_vrf.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ecs_vrf.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+ecs_vrf.o: ecs_locl.h ecs_vrf.c
diff --git a/crypto/engine/Makefile b/crypto/engine/Makefile
index 13f211a..0cc3722 100644
--- a/crypto/engine/Makefile
+++ b/crypto/engine/Makefile
@@ -41,7 +41,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -82,88 +82,146 @@
 
 # DO NOT DELETE THIS LINE -- make depend depends on it.
 
-eng_all.o: ../../e_os.h ../../include/openssl/bio.h
-eng_all.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-eng_all.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-eng_all.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+eng_all.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_all.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_all.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+eng_all.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+eng_all.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+eng_all.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+eng_all.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+eng_all.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 eng_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-eng_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+eng_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+eng_all.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 eng_all.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+eng_all.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
 eng_all.o: ../cryptlib.h eng_all.c eng_int.h
-eng_cnf.o: ../../e_os.h ../../include/openssl/bio.h
-eng_cnf.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
-eng_cnf.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+eng_cnf.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_cnf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_cnf.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+eng_cnf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+eng_cnf.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 eng_cnf.o: ../../include/openssl/engine.h ../../include/openssl/err.h
-eng_cnf.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+eng_cnf.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+eng_cnf.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+eng_cnf.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 eng_cnf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-eng_cnf.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_cnf.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_cnf.c eng_int.h
+eng_cnf.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+eng_cnf.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+eng_cnf.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+eng_cnf.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_cnf.c eng_int.h
 eng_cryptodev.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-eng_cryptodev.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-eng_cryptodev.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-eng_cryptodev.o: ../../include/openssl/evp.h ../../include/openssl/obj_mac.h
+eng_cryptodev.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+eng_cryptodev.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+eng_cryptodev.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+eng_cryptodev.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+eng_cryptodev.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+eng_cryptodev.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
 eng_cryptodev.o: ../../include/openssl/objects.h
 eng_cryptodev.o: ../../include/openssl/opensslconf.h
 eng_cryptodev.o: ../../include/openssl/opensslv.h
-eng_cryptodev.o: ../../include/openssl/ossl_typ.h
-eng_cryptodev.o: ../../include/openssl/safestack.h
+eng_cryptodev.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+eng_cryptodev.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 eng_cryptodev.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+eng_cryptodev.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
 eng_cryptodev.o: eng_cryptodev.c
-eng_ctrl.o: ../../e_os.h ../../include/openssl/bio.h
-eng_ctrl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-eng_ctrl.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-eng_ctrl.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+eng_ctrl.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_ctrl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_ctrl.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+eng_ctrl.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+eng_ctrl.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+eng_ctrl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+eng_ctrl.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+eng_ctrl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 eng_ctrl.o: ../../include/openssl/opensslconf.h
 eng_ctrl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-eng_ctrl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_ctrl.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_ctrl.c eng_int.h
-eng_dyn.o: ../../e_os.h ../../include/openssl/bio.h
-eng_dyn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-eng_dyn.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
+eng_ctrl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+eng_ctrl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+eng_ctrl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+eng_ctrl.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_ctrl.c eng_int.h
+eng_dyn.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_dyn.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_dyn.o: ../../include/openssl/crypto.h ../../include/openssl/dso.h
+eng_dyn.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+eng_dyn.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 eng_dyn.o: ../../include/openssl/engine.h ../../include/openssl/err.h
-eng_dyn.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+eng_dyn.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+eng_dyn.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+eng_dyn.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 eng_dyn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-eng_dyn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_dyn.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_dyn.c eng_int.h
-eng_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
-eng_err.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-eng_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-eng_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-eng_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-eng_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-eng_err.o: eng_err.c
-eng_fat.o: ../../e_os.h ../../include/openssl/bio.h
-eng_fat.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
-eng_fat.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+eng_dyn.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+eng_dyn.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+eng_dyn.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+eng_dyn.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_dyn.c eng_int.h
+eng_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+eng_err.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+eng_err.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+eng_err.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+eng_err.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+eng_err.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+eng_err.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+eng_err.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+eng_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+eng_err.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+eng_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+eng_err.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+eng_err.o: ../../include/openssl/x509_vfy.h eng_err.c
+eng_fat.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_fat.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_fat.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+eng_fat.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+eng_fat.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 eng_fat.o: ../../include/openssl/engine.h ../../include/openssl/err.h
-eng_fat.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+eng_fat.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+eng_fat.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+eng_fat.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 eng_fat.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-eng_fat.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_fat.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_fat.c eng_int.h
-eng_init.o: ../../e_os.h ../../include/openssl/bio.h
-eng_init.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-eng_init.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-eng_init.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+eng_fat.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+eng_fat.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+eng_fat.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+eng_fat.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_fat.c eng_int.h
+eng_init.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_init.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_init.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+eng_init.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+eng_init.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+eng_init.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+eng_init.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+eng_init.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 eng_init.o: ../../include/openssl/opensslconf.h
 eng_init.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-eng_init.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_init.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_init.c eng_int.h
-eng_lib.o: ../../e_os.h ../../include/openssl/bio.h
-eng_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-eng_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-eng_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+eng_init.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+eng_init.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+eng_init.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+eng_init.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_init.c eng_int.h
+eng_lib.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+eng_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+eng_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+eng_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+eng_lib.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+eng_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 eng_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-eng_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-eng_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_int.h eng_lib.c
-eng_list.o: ../../e_os.h ../../include/openssl/bio.h
-eng_list.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-eng_list.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-eng_list.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+eng_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+eng_lib.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+eng_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+eng_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+eng_lib.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h eng_lib.c
+eng_list.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_list.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_list.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+eng_list.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+eng_list.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+eng_list.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+eng_list.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+eng_list.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 eng_list.o: ../../include/openssl/opensslconf.h
 eng_list.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-eng_list.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_list.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_int.h eng_list.c
+eng_list.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+eng_list.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+eng_list.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+eng_list.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h eng_list.c
 eng_openssl.o: ../../e_os.h ../../include/openssl/asn1.h
 eng_openssl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 eng_openssl.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
@@ -171,8 +229,9 @@
 eng_openssl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 eng_openssl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 eng_openssl.o: ../../include/openssl/engine.h ../../include/openssl/err.h
-eng_openssl.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-eng_openssl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+eng_openssl.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+eng_openssl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+eng_openssl.o: ../../include/openssl/objects.h
 eng_openssl.o: ../../include/openssl/opensslconf.h
 eng_openssl.o: ../../include/openssl/opensslv.h
 eng_openssl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
@@ -183,106 +242,172 @@
 eng_openssl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
 eng_openssl.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_openssl.c
 eng_padlock.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
-eng_padlock.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
-eng_padlock.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
+eng_padlock.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_padlock.o: ../../include/openssl/crypto.h ../../include/openssl/dso.h
+eng_padlock.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+eng_padlock.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 eng_padlock.o: ../../include/openssl/engine.h ../../include/openssl/err.h
-eng_padlock.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-eng_padlock.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+eng_padlock.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+eng_padlock.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+eng_padlock.o: ../../include/openssl/objects.h
 eng_padlock.o: ../../include/openssl/opensslconf.h
 eng_padlock.o: ../../include/openssl/opensslv.h
-eng_padlock.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-eng_padlock.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_padlock.o: ../../include/openssl/symhacks.h eng_padlock.c
-eng_pkey.o: ../../e_os.h ../../include/openssl/bio.h
-eng_pkey.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-eng_pkey.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-eng_pkey.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+eng_padlock.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+eng_padlock.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+eng_padlock.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+eng_padlock.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+eng_padlock.o: ../../include/openssl/x509_vfy.h eng_padlock.c
+eng_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
+eng_pkey.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+eng_pkey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+eng_pkey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+eng_pkey.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+eng_pkey.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+eng_pkey.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+eng_pkey.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 eng_pkey.o: ../../include/openssl/opensslconf.h
 eng_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-eng_pkey.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_pkey.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_int.h eng_pkey.c
+eng_pkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+eng_pkey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+eng_pkey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+eng_pkey.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h eng_pkey.c
 eng_table.o: ../../e_os.h ../../include/openssl/asn1.h
 eng_table.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 eng_table.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-eng_table.o: ../../include/openssl/engine.h ../../include/openssl/err.h
-eng_table.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+eng_table.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+eng_table.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+eng_table.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+eng_table.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
 eng_table.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 eng_table.o: ../../include/openssl/opensslconf.h
 eng_table.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-eng_table.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-eng_table.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_int.h
+eng_table.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+eng_table.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+eng_table.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+eng_table.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
 eng_table.o: eng_table.c
-tb_cipher.o: ../../e_os.h ../../include/openssl/bio.h
-tb_cipher.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-tb_cipher.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-tb_cipher.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+tb_cipher.o: ../../e_os.h ../../include/openssl/asn1.h
+tb_cipher.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+tb_cipher.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+tb_cipher.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+tb_cipher.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+tb_cipher.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+tb_cipher.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+tb_cipher.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 tb_cipher.o: ../../include/openssl/opensslconf.h
 tb_cipher.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-tb_cipher.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-tb_cipher.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_int.h
+tb_cipher.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+tb_cipher.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+tb_cipher.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+tb_cipher.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
 tb_cipher.o: tb_cipher.c
-tb_dh.o: ../../e_os.h ../../include/openssl/bio.h
+tb_dh.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 tb_dh.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-tb_dh.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-tb_dh.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-tb_dh.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-tb_dh.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-tb_dh.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-tb_dh.o: ../cryptlib.h eng_int.h tb_dh.c
-tb_digest.o: ../../e_os.h ../../include/openssl/bio.h
-tb_digest.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-tb_digest.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-tb_digest.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+tb_dh.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+tb_dh.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+tb_dh.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+tb_dh.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+tb_dh.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+tb_dh.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+tb_dh.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+tb_dh.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+tb_dh.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+tb_dh.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+tb_dh.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_dh.c
+tb_digest.o: ../../e_os.h ../../include/openssl/asn1.h
+tb_digest.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+tb_digest.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+tb_digest.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+tb_digest.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+tb_digest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+tb_digest.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+tb_digest.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 tb_digest.o: ../../include/openssl/opensslconf.h
 tb_digest.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-tb_digest.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-tb_digest.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_int.h
+tb_digest.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+tb_digest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+tb_digest.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+tb_digest.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
 tb_digest.o: tb_digest.c
-tb_dsa.o: ../../e_os.h ../../include/openssl/bio.h
+tb_dsa.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 tb_dsa.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-tb_dsa.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-tb_dsa.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-tb_dsa.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-tb_dsa.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-tb_dsa.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-tb_dsa.o: ../cryptlib.h eng_int.h tb_dsa.c
-tb_ecdh.o: ../../e_os.h ../../include/openssl/bio.h
-tb_ecdh.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-tb_ecdh.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-tb_ecdh.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+tb_dsa.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+tb_dsa.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+tb_dsa.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+tb_dsa.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+tb_dsa.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+tb_dsa.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+tb_dsa.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+tb_dsa.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+tb_dsa.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+tb_dsa.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+tb_dsa.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_dsa.c
+tb_ecdh.o: ../../e_os.h ../../include/openssl/asn1.h
+tb_ecdh.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+tb_ecdh.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+tb_ecdh.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+tb_ecdh.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+tb_ecdh.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+tb_ecdh.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+tb_ecdh.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 tb_ecdh.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-tb_ecdh.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+tb_ecdh.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+tb_ecdh.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 tb_ecdh.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+tb_ecdh.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
 tb_ecdh.o: ../cryptlib.h eng_int.h tb_ecdh.c
-tb_ecdsa.o: ../../e_os.h ../../include/openssl/bio.h
-tb_ecdsa.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-tb_ecdsa.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-tb_ecdsa.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+tb_ecdsa.o: ../../e_os.h ../../include/openssl/asn1.h
+tb_ecdsa.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+tb_ecdsa.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+tb_ecdsa.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+tb_ecdsa.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+tb_ecdsa.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+tb_ecdsa.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+tb_ecdsa.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 tb_ecdsa.o: ../../include/openssl/opensslconf.h
 tb_ecdsa.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-tb_ecdsa.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-tb_ecdsa.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_int.h tb_ecdsa.c
-tb_rand.o: ../../e_os.h ../../include/openssl/bio.h
-tb_rand.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-tb_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-tb_rand.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+tb_ecdsa.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+tb_ecdsa.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+tb_ecdsa.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+tb_ecdsa.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_ecdsa.c
+tb_rand.o: ../../e_os.h ../../include/openssl/asn1.h
+tb_rand.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+tb_rand.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+tb_rand.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+tb_rand.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+tb_rand.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+tb_rand.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+tb_rand.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 tb_rand.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-tb_rand.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+tb_rand.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+tb_rand.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 tb_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+tb_rand.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
 tb_rand.o: ../cryptlib.h eng_int.h tb_rand.c
-tb_rsa.o: ../../e_os.h ../../include/openssl/bio.h
+tb_rsa.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 tb_rsa.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-tb_rsa.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-tb_rsa.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-tb_rsa.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-tb_rsa.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-tb_rsa.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-tb_rsa.o: ../cryptlib.h eng_int.h tb_rsa.c
-tb_store.o: ../../e_os.h ../../include/openssl/bio.h
-tb_store.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-tb_store.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-tb_store.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+tb_rsa.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+tb_rsa.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+tb_rsa.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+tb_rsa.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+tb_rsa.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+tb_rsa.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+tb_rsa.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+tb_rsa.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+tb_rsa.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+tb_rsa.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+tb_rsa.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_rsa.c
+tb_store.o: ../../e_os.h ../../include/openssl/asn1.h
+tb_store.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+tb_store.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+tb_store.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+tb_store.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+tb_store.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+tb_store.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+tb_store.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 tb_store.o: ../../include/openssl/opensslconf.h
 tb_store.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-tb_store.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-tb_store.o: ../../include/openssl/symhacks.h ../cryptlib.h eng_int.h tb_store.c
+tb_store.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+tb_store.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+tb_store.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+tb_store.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h tb_store.c
diff --git a/crypto/engine/eng_all.c b/crypto/engine/eng_all.c
index 8599046..d29cd57 100644
--- a/crypto/engine/eng_all.c
+++ b/crypto/engine/eng_all.c
@@ -107,6 +107,9 @@
 #if defined(__OpenBSD__) || defined(__FreeBSD__)
 	ENGINE_load_cryptodev();
 #endif
+#if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
+	ENGINE_load_capi();
+#endif
 #endif
 	}
 
diff --git a/crypto/engine/eng_cnf.c b/crypto/engine/eng_cnf.c
index a97e01e..08066ce 100644
--- a/crypto/engine/eng_cnf.c
+++ b/crypto/engine/eng_cnf.c
@@ -1,5 +1,5 @@
 /* eng_cnf.c */
-/* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
  * project 2001.
  */
 /* ====================================================================
@@ -98,6 +98,8 @@
 	CONF_VALUE *ecmd;
 	char *ctrlname, *ctrlvalue;
 	ENGINE *e = NULL;
+	int soft = 0;
+
 	name = skip_dot(name);
 #ifdef ENGINE_CONF_DEBUG
 	fprintf(stderr, "Configuring engine %s\n", name);
@@ -125,6 +127,8 @@
 		/* Override engine name to use */
 		if (!strcmp(ctrlname, "engine_id"))
 			name = ctrlvalue;
+		else if (!strcmp(ctrlname, "soft_load"))
+			soft = 1;
 		/* Load a dynamic ENGINE */
 		else if (!strcmp(ctrlname, "dynamic_path"))
 			{
@@ -147,6 +151,11 @@
 			if (!e)
 				{
 				e = ENGINE_by_id(name);
+				if (!e && soft)
+					{
+					ERR_clear_error();
+					return 1;
+					}
 				if (!e)
 					return 0;
 				}
diff --git a/crypto/engine/eng_err.c b/crypto/engine/eng_err.c
index 369f2e2..574ffbb 100644
--- a/crypto/engine/eng_err.c
+++ b/crypto/engine/eng_err.c
@@ -1,6 +1,6 @@
 /* crypto/engine/eng_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-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
@@ -92,6 +92,7 @@
 {ERR_FUNC(ENGINE_F_ENGINE_LIST_REMOVE),	"ENGINE_LIST_REMOVE"},
 {ERR_FUNC(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY),	"ENGINE_load_private_key"},
 {ERR_FUNC(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY),	"ENGINE_load_public_key"},
+{ERR_FUNC(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT),	"ENGINE_load_ssl_client_cert"},
 {ERR_FUNC(ENGINE_F_ENGINE_NEW),	"ENGINE_new"},
 {ERR_FUNC(ENGINE_F_ENGINE_REMOVE),	"ENGINE_remove"},
 {ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_STRING),	"ENGINE_set_default_string"},
diff --git a/crypto/engine/eng_int.h b/crypto/engine/eng_int.h
index a5b1ede..a66f107 100644
--- a/crypto/engine/eng_int.h
+++ b/crypto/engine/eng_int.h
@@ -170,6 +170,8 @@
 	ENGINE_LOAD_KEY_PTR load_privkey;
 	ENGINE_LOAD_KEY_PTR load_pubkey;
 
+	ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert;
+
 	const ENGINE_CMD_DEFN *cmd_defns;
 	int flags;
 	/* reference count on the structure itself */
diff --git a/crypto/engine/eng_padlock.c b/crypto/engine/eng_padlock.c
index 1ba9d85..743558a 100644
--- a/crypto/engine/eng_padlock.c
+++ b/crypto/engine/eng_padlock.c
@@ -234,8 +234,8 @@
 	return 1;
 }
 
-IMPLEMENT_DYNAMIC_CHECK_FN ();
-IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn);
+IMPLEMENT_DYNAMIC_CHECK_FN ()
+IMPLEMENT_DYNAMIC_BIND_FN (padlock_bind_fn)
 #endif /* DYNAMIC_ENGINE */
 
 /* ===== Here comes the "real" engine ===== */
diff --git a/crypto/engine/eng_pkey.c b/crypto/engine/eng_pkey.c
index bc8b21a..1dfa2e3 100644
--- a/crypto/engine/eng_pkey.c
+++ b/crypto/engine/eng_pkey.c
@@ -69,6 +69,13 @@
 	return 1;
 	}
 
+int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
+				ENGINE_SSL_CLIENT_CERT_PTR loadssl_f)
+	{
+	e->load_ssl_client_cert = loadssl_f;
+	return 1;
+	}
+
 ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e)
 	{
 	return e->load_privkey;
@@ -79,6 +86,11 @@
 	return e->load_pubkey;
 	}
 
+ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e)
+	{
+	return e->load_ssl_client_cert;
+	}
+
 /* API functions to load public/private keys */
 
 EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
@@ -152,3 +164,33 @@
 		}
 	return pkey;
 	}
+
+int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
+	STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey,
+	STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data)
+	{
+
+	if(e == NULL)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
+			ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+		}
+	CRYPTO_w_lock(CRYPTO_LOCK_ENGINE);
+	if(e->funct_ref == 0)
+		{
+		CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
+			ENGINE_R_NOT_INITIALISED);
+		return 0;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE);
+	if (!e->load_ssl_client_cert)
+		{
+		ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT,
+			ENGINE_R_NO_LOAD_FUNCTION);
+		return 0;
+		}
+	return e->load_ssl_client_cert(e, s, ca_dn, pcert, ppkey, pother,
+					ui_method, callback_data);
+	}
diff --git a/crypto/engine/engine.h b/crypto/engine/engine.h
index 3ec5933..f503595 100644
--- a/crypto/engine/engine.h
+++ b/crypto/engine/engine.h
@@ -93,6 +93,8 @@
 #include <openssl/err.h>
 #endif
 
+#include <openssl/x509.h>
+
 #include <openssl/ossl_typ.h>
 #include <openssl/symhacks.h>
 
@@ -278,6 +280,9 @@
 /* Generic load_key function pointer */
 typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
 	UI_METHOD *ui_method, void *callback_data);
+typedef int (*ENGINE_SSL_CLIENT_CERT_PTR)(ENGINE *, SSL *ssl,
+	STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **pkey,
+	STACK_OF(X509) **pother, UI_METHOD *ui_method, void *callback_data);
 /* These callback types are for an ENGINE's handler for cipher and digest logic.
  * These handlers have these prototypes;
  *   int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
@@ -334,6 +339,9 @@
 void ENGINE_load_cryptodev(void);
 void ENGINE_load_padlock(void);
 void ENGINE_load_builtin_engines(void);
+#ifndef OPENSSL_NO_CAPIENG
+void ENGINE_load_capi(void);
+#endif
 
 /* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
  * "registry" handling. */
@@ -459,6 +467,8 @@
 int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
 int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f);
 int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
+int ENGINE_set_load_ssl_client_cert_function(ENGINE *e,
+				ENGINE_SSL_CLIENT_CERT_PTR loadssl_f);
 int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
 int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
 int ENGINE_set_flags(ENGINE *e, int flags);
@@ -494,6 +504,7 @@
 ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
 ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
 ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
+ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE *e);
 ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
 ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
 const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
@@ -529,6 +540,10 @@
 	UI_METHOD *ui_method, void *callback_data);
 EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
 	UI_METHOD *ui_method, void *callback_data);
+int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s,
+	STACK_OF(X509_NAME) *ca_dn, X509 **pcert, EVP_PKEY **ppkey,
+	STACK_OF(X509) **pother,
+	UI_METHOD *ui_method, void *callback_data);
 
 /* This returns a pointer for the current ENGINE structure that
  * is (by default) performing any RSA operations. The value returned
@@ -723,6 +738,7 @@
 #define ENGINE_F_ENGINE_LIST_REMOVE			 121
 #define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY		 150
 #define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY			 151
+#define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT		 192
 #define ENGINE_F_ENGINE_NEW				 122
 #define ENGINE_F_ENGINE_REMOVE				 123
 #define ENGINE_F_ENGINE_SET_DEFAULT_STRING		 189
diff --git a/crypto/engine/enginetest.c b/crypto/engine/enginetest.c
index cf82f49..e383461 100644
--- a/crypto/engine/enginetest.c
+++ b/crypto/engine/enginetest.c
@@ -58,6 +58,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <openssl/e_os2.h>
 
 #ifdef OPENSSL_NO_ENGINE
 int main(int argc, char *argv[])
@@ -66,7 +67,6 @@
     return(0);
 }
 #else
-#include <openssl/e_os2.h>
 #include <openssl/buffer.h>
 #include <openssl/crypto.h>
 #include <openssl/engine.h>
diff --git a/crypto/err/Makefile b/crypto/err/Makefile
index 23e3840..91d1379 100644
--- a/crypto/err/Makefile
+++ b/crypto/err/Makefile
@@ -17,8 +17,8 @@
 APPS=
 
 LIB=$(TOP)/libcrypto.a
-LIBSRC=err.c err_all.c err_prn.c
-LIBOBJ=err.o err_all.o err_prn.o
+LIBSRC=err.c err_def.c err_all.c err_prn.c err_str.c err_bio.c
+LIBOBJ=err.o err_def.o err_all.o err_prn.o err_str.o err_bio.o
 
 SRC= $(LIBSRC)
 
@@ -33,7 +33,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -89,17 +89,31 @@
 err_all.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 err_all.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
 err_all.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-err_all.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-err_all.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
-err_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-err_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem2.h
-err_all.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
-err_all.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
-err_all.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-err_all.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-err_all.o: ../../include/openssl/ui.h ../../include/openssl/x509.h
-err_all.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-err_all.o: err_all.c
+err_all.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+err_all.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+err_all.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
+err_all.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+err_all.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs12.h
+err_all.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+err_all.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+err_all.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+err_all.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+err_all.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+err_all.o: ../../include/openssl/x509v3.h err_all.c
+err_bio.o: ../../e_os.h ../../include/openssl/bio.h
+err_bio.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+err_bio.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+err_bio.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+err_bio.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+err_bio.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+err_bio.o: ../../include/openssl/symhacks.h ../cryptlib.h err_bio.c
+err_def.o: ../../e_os.h ../../include/openssl/bio.h
+err_def.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+err_def.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+err_def.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+err_def.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+err_def.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+err_def.o: ../../include/openssl/symhacks.h ../cryptlib.h err_def.c
 err_prn.o: ../../e_os.h ../../include/openssl/bio.h
 err_prn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 err_prn.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
@@ -107,3 +121,10 @@
 err_prn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 err_prn.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 err_prn.o: ../../include/openssl/symhacks.h ../cryptlib.h err_prn.c
+err_str.o: ../../e_os.h ../../include/openssl/bio.h
+err_str.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+err_str.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+err_str.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+err_str.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+err_str.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+err_str.o: ../../include/openssl/symhacks.h ../cryptlib.h err_str.c
diff --git a/crypto/err/err.c b/crypto/err/err.c
index b6ff070..292404a 100644
--- a/crypto/err/err.c
+++ b/crypto/err/err.c
@@ -119,479 +119,9 @@
 #include <openssl/bio.h>
 #include <openssl/err.h>
 
-static void err_load_strings(int lib, ERR_STRING_DATA *str);
-
-static void ERR_STATE_free(ERR_STATE *s);
-#ifndef OPENSSL_NO_ERR
-static ERR_STRING_DATA ERR_str_libraries[]=
-	{
-{ERR_PACK(ERR_LIB_NONE,0,0)		,"unknown library"},
-{ERR_PACK(ERR_LIB_SYS,0,0)		,"system library"},
-{ERR_PACK(ERR_LIB_BN,0,0)		,"bignum routines"},
-{ERR_PACK(ERR_LIB_RSA,0,0)		,"rsa routines"},
-{ERR_PACK(ERR_LIB_DH,0,0)		,"Diffie-Hellman routines"},
-{ERR_PACK(ERR_LIB_EVP,0,0)		,"digital envelope routines"},
-{ERR_PACK(ERR_LIB_BUF,0,0)		,"memory buffer routines"},
-{ERR_PACK(ERR_LIB_OBJ,0,0)		,"object identifier routines"},
-{ERR_PACK(ERR_LIB_PEM,0,0)		,"PEM routines"},
-{ERR_PACK(ERR_LIB_DSA,0,0)		,"dsa routines"},
-{ERR_PACK(ERR_LIB_X509,0,0)		,"x509 certificate routines"},
-{ERR_PACK(ERR_LIB_ASN1,0,0)		,"asn1 encoding routines"},
-{ERR_PACK(ERR_LIB_CONF,0,0)		,"configuration file routines"},
-{ERR_PACK(ERR_LIB_CRYPTO,0,0)		,"common libcrypto routines"},
-{ERR_PACK(ERR_LIB_EC,0,0)		,"elliptic curve routines"},
-{ERR_PACK(ERR_LIB_SSL,0,0)		,"SSL routines"},
-{ERR_PACK(ERR_LIB_BIO,0,0)		,"BIO routines"},
-{ERR_PACK(ERR_LIB_PKCS7,0,0)		,"PKCS7 routines"},
-{ERR_PACK(ERR_LIB_X509V3,0,0)		,"X509 V3 routines"},
-{ERR_PACK(ERR_LIB_PKCS12,0,0)		,"PKCS12 routines"},
-{ERR_PACK(ERR_LIB_RAND,0,0)		,"random number generator"},
-{ERR_PACK(ERR_LIB_DSO,0,0)		,"DSO support routines"},
-{ERR_PACK(ERR_LIB_ENGINE,0,0)		,"engine routines"},
-{ERR_PACK(ERR_LIB_OCSP,0,0)		,"OCSP routines"},
-{ERR_PACK(ERR_LIB_CMS,0,0)		,"CMS routines"},
-{0,NULL},
-	};
-
-static ERR_STRING_DATA ERR_str_functs[]=
-	{
-	{ERR_PACK(0,SYS_F_FOPEN,0),     	"fopen"},
-	{ERR_PACK(0,SYS_F_CONNECT,0),		"connect"},
-	{ERR_PACK(0,SYS_F_GETSERVBYNAME,0),	"getservbyname"},
-	{ERR_PACK(0,SYS_F_SOCKET,0),		"socket"}, 
-	{ERR_PACK(0,SYS_F_IOCTLSOCKET,0),	"ioctlsocket"},
-	{ERR_PACK(0,SYS_F_BIND,0),		"bind"},
-	{ERR_PACK(0,SYS_F_LISTEN,0),		"listen"},
-	{ERR_PACK(0,SYS_F_ACCEPT,0),		"accept"},
-#ifdef OPENSSL_SYS_WINDOWS
-	{ERR_PACK(0,SYS_F_WSASTARTUP,0),	"WSAstartup"},
-#endif
-	{ERR_PACK(0,SYS_F_OPENDIR,0),		"opendir"},
-	{ERR_PACK(0,SYS_F_FREAD,0),		"fread"},
-	{0,NULL},
-	};
-
-static ERR_STRING_DATA ERR_str_reasons[]=
-	{
-{ERR_R_SYS_LIB				,"system lib"},
-{ERR_R_BN_LIB				,"BN lib"},
-{ERR_R_RSA_LIB				,"RSA lib"},
-{ERR_R_DH_LIB				,"DH lib"},
-{ERR_R_EVP_LIB				,"EVP lib"},
-{ERR_R_BUF_LIB				,"BUF lib"},
-{ERR_R_OBJ_LIB				,"OBJ lib"},
-{ERR_R_PEM_LIB				,"PEM lib"},
-{ERR_R_DSA_LIB				,"DSA lib"},
-{ERR_R_X509_LIB				,"X509 lib"},
-{ERR_R_ASN1_LIB				,"ASN1 lib"},
-{ERR_R_CONF_LIB				,"CONF lib"},
-{ERR_R_CRYPTO_LIB			,"CRYPTO lib"},
-{ERR_R_EC_LIB				,"EC lib"},
-{ERR_R_SSL_LIB				,"SSL lib"},
-{ERR_R_BIO_LIB				,"BIO lib"},
-{ERR_R_PKCS7_LIB			,"PKCS7 lib"},
-{ERR_R_X509V3_LIB			,"X509V3 lib"},
-{ERR_R_PKCS12_LIB			,"PKCS12 lib"},
-{ERR_R_RAND_LIB				,"RAND lib"},
-{ERR_R_DSO_LIB				,"DSO lib"},
-{ERR_R_ENGINE_LIB			,"ENGINE lib"},
-{ERR_R_OCSP_LIB				,"OCSP lib"},
-
-{ERR_R_NESTED_ASN1_ERROR		,"nested asn1 error"},
-{ERR_R_BAD_ASN1_OBJECT_HEADER		,"bad asn1 object header"},
-{ERR_R_BAD_GET_ASN1_OBJECT_CALL		,"bad get asn1 object call"},
-{ERR_R_EXPECTING_AN_ASN1_SEQUENCE	,"expecting an asn1 sequence"},
-{ERR_R_ASN1_LENGTH_MISMATCH		,"asn1 length mismatch"},
-{ERR_R_MISSING_ASN1_EOS			,"missing asn1 eos"},
-
-{ERR_R_FATAL                            ,"fatal"},
-{ERR_R_MALLOC_FAILURE			,"malloc failure"},
-{ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED	,"called a function you should not call"},
-{ERR_R_PASSED_NULL_PARAMETER		,"passed a null parameter"},
-{ERR_R_INTERNAL_ERROR			,"internal error"},
-{ERR_R_DISABLED				,"called a function that was disabled at compile-time"},
-
-{0,NULL},
-	};
-#endif
-
-
-/* Define the predeclared (but externally opaque) "ERR_FNS" type */
-struct st_ERR_FNS
-	{
-	/* Works on the "error_hash" string table */
-	LHASH *(*cb_err_get)(int create);
-	void (*cb_err_del)(void);
-	ERR_STRING_DATA *(*cb_err_get_item)(const ERR_STRING_DATA *);
-	ERR_STRING_DATA *(*cb_err_set_item)(ERR_STRING_DATA *);
-	ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *);
-	/* Works on the "thread_hash" error-state table */
-	LHASH *(*cb_thread_get)(int create);
-	void (*cb_thread_release)(LHASH **hash);
-	ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *);
-	ERR_STATE *(*cb_thread_set_item)(ERR_STATE *);
-	void (*cb_thread_del_item)(const ERR_STATE *);
-	/* Returns the next available error "library" numbers */
-	int (*cb_get_next_lib)(void);
-	};
-
-/* Predeclarations of the "err_defaults" functions */
-static LHASH *int_err_get(int create);
-static void int_err_del(void);
-static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
-static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *);
-static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *);
-static LHASH *int_thread_get(int create);
-static void int_thread_release(LHASH **hash);
-static ERR_STATE *int_thread_get_item(const ERR_STATE *);
-static ERR_STATE *int_thread_set_item(ERR_STATE *);
-static void int_thread_del_item(const ERR_STATE *);
-static int int_err_get_next_lib(void);
-/* The static ERR_FNS table using these defaults functions */
-static const ERR_FNS err_defaults =
-	{
-	int_err_get,
-	int_err_del,
-	int_err_get_item,
-	int_err_set_item,
-	int_err_del_item,
-	int_thread_get,
-	int_thread_release,
-	int_thread_get_item,
-	int_thread_set_item,
-	int_thread_del_item,
-	int_err_get_next_lib
-	};
-
-/* The replacable table of ERR_FNS functions we use at run-time */
-static const ERR_FNS *err_fns = NULL;
-
-/* Eg. rather than using "err_get()", use "ERRFN(err_get)()". */
-#define ERRFN(a) err_fns->cb_##a
-
-/* The internal state used by "err_defaults" - as such, the setting, reading,
- * creating, and deleting of this data should only be permitted via the
- * "err_defaults" functions. This way, a linked module can completely defer all
- * ERR state operation (together with requisite locking) to the implementations
- * and state in the loading application. */
-static LHASH *int_error_hash = NULL;
-static LHASH *int_thread_hash = NULL;
-static int int_thread_hash_references = 0;
-static int int_err_library_number= ERR_LIB_USER;
-
-/* Internal function that checks whether "err_fns" is set and if not, sets it to
- * the defaults. */
-static void err_fns_check(void)
-	{
-	if (err_fns) return;
-	
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	if (!err_fns)
-		err_fns = &err_defaults;
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-	}
-
-/* API functions to get or set the underlying ERR functions. */
-
-const ERR_FNS *ERR_get_implementation(void)
-	{
-	err_fns_check();
-	return err_fns;
-	}
-
-int ERR_set_implementation(const ERR_FNS *fns)
-	{
-	int ret = 0;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	/* It's too late if 'err_fns' is non-NULL. BTW: not much point setting
-	 * an error is there?! */
-	if (!err_fns)
-		{
-		err_fns = fns;
-		ret = 1;
-		}
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-	return ret;
-	}
-
-/* These are the callbacks provided to "lh_new()" when creating the LHASH tables
- * internal to the "err_defaults" implementation. */
-
-/* static unsigned long err_hash(ERR_STRING_DATA *a); */
-static unsigned long err_hash(const void *a_void);
-/* static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b); */
-static int err_cmp(const void *a_void, const void *b_void);
-/* static unsigned long pid_hash(ERR_STATE *pid); */
-static unsigned long pid_hash(const void *pid_void);
-/* static int pid_cmp(ERR_STATE *a,ERR_STATE *pid); */
-static int pid_cmp(const void *a_void,const void *pid_void);
-static unsigned long get_error_values(int inc,int top,const char **file,int *line,
-				      const char **data,int *flags);
-
-/* The internal functions used in the "err_defaults" implementation */
-
-static LHASH *int_err_get(int create)
-	{
-	LHASH *ret = NULL;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	if (!int_error_hash && create)
-		{
-		CRYPTO_push_info("int_err_get (err.c)");
-		int_error_hash = lh_new(err_hash, err_cmp);
-		CRYPTO_pop_info();
-		}
-	if (int_error_hash)
-		ret = int_error_hash;
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-
-	return ret;
-	}
-
-static void int_err_del(void)
-	{
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	if (int_error_hash)
-		{
-		lh_free(int_error_hash);
-		int_error_hash = NULL;
-		}
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-	}
-
-static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d)
-	{
-	ERR_STRING_DATA *p;
-	LHASH *hash;
-
-	err_fns_check();
-	hash = ERRFN(err_get)(0);
-	if (!hash)
-		return NULL;
-
-	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
-	p = (ERR_STRING_DATA *)lh_retrieve(hash, d);
-	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
-
-	return p;
-	}
-
-static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d)
-	{
-	ERR_STRING_DATA *p;
-	LHASH *hash;
-
-	err_fns_check();
-	hash = ERRFN(err_get)(1);
-	if (!hash)
-		return NULL;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	p = (ERR_STRING_DATA *)lh_insert(hash, d);
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-
-	return p;
-	}
-
-static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d)
-	{
-	ERR_STRING_DATA *p;
-	LHASH *hash;
-
-	err_fns_check();
-	hash = ERRFN(err_get)(0);
-	if (!hash)
-		return NULL;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	p = (ERR_STRING_DATA *)lh_delete(hash, d);
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-
-	return p;
-	}
-
-static LHASH *int_thread_get(int create)
-	{
-	LHASH *ret = NULL;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	if (!int_thread_hash && create)
-		{
-		CRYPTO_push_info("int_thread_get (err.c)");
-		int_thread_hash = lh_new(pid_hash, pid_cmp);
-		CRYPTO_pop_info();
-		}
-	if (int_thread_hash)
-		{
-		int_thread_hash_references++;
-		ret = int_thread_hash;
-		}
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-	return ret;
-	}
-
-static void int_thread_release(LHASH **hash)
-	{
-	int i;
-
-	if (hash == NULL || *hash == NULL)
-		return;
-
-	i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR);
-
-#ifdef REF_PRINT
-	fprintf(stderr,"%4d:%s\n",int_thread_hash_references,"ERR");
-#endif
-	if (i > 0) return;
-#ifdef REF_CHECK
-	if (i < 0)
-		{
-		fprintf(stderr,"int_thread_release, bad reference count\n");
-		abort(); /* ok */
-		}
-#endif
-	*hash = NULL;
-	}
-
-static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
-	{
-	ERR_STATE *p;
-	LHASH *hash;
-
-	err_fns_check();
-	hash = ERRFN(thread_get)(0);
-	if (!hash)
-		return NULL;
-
-	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
-	p = (ERR_STATE *)lh_retrieve(hash, d);
-	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
-
-	ERRFN(thread_release)(&hash);
-	return p;
-	}
-
-static ERR_STATE *int_thread_set_item(ERR_STATE *d)
-	{
-	ERR_STATE *p;
-	LHASH *hash;
-
-	err_fns_check();
-	hash = ERRFN(thread_get)(1);
-	if (!hash)
-		return NULL;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	p = (ERR_STATE *)lh_insert(hash, d);
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-
-	ERRFN(thread_release)(&hash);
-	return p;
-	}
-
-static void int_thread_del_item(const ERR_STATE *d)
-	{
-	ERR_STATE *p;
-	LHASH *hash;
-
-	err_fns_check();
-	hash = ERRFN(thread_get)(0);
-	if (!hash)
-		return;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	p = (ERR_STATE *)lh_delete(hash, d);
-	/* make sure we don't leak memory */
-	if (int_thread_hash_references == 1
-		&& int_thread_hash && (lh_num_items(int_thread_hash) == 0))
-		{
-		lh_free(int_thread_hash);
-		int_thread_hash = NULL;
-		}
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-
-	ERRFN(thread_release)(&hash);
-	if (p)
-		ERR_STATE_free(p);
-	}
-
-static int int_err_get_next_lib(void)
-	{
-	int ret;
-
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	ret = int_err_library_number++;
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-
-	return ret;
-	}
-
-
-#ifndef OPENSSL_NO_ERR
-#define NUM_SYS_STR_REASONS 127
-#define LEN_SYS_STR_REASON 32
-
-static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
-/* SYS_str_reasons is filled with copies of strerror() results at
- * initialization.
- * 'errno' values up to 127 should cover all usual errors,
- * others will be displayed numerically by ERR_error_string.
- * It is crucial that we have something for each reason code
- * that occurs in ERR_str_reasons, or bogus reason strings
- * will be returned for SYSerr(), which always gets an errno
- * value and never one of those 'standard' reason codes. */
-
-static void build_SYS_str_reasons(void)
-	{
-	/* OPENSSL_malloc cannot be used here, use static storage instead */
-	static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
-	int i;
-	static int init = 1;
-
-	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
-	if (!init)
-		{
-		CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
-		return;
-		}
-	
-	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
-	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
-	if (!init)
-		{
-		CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-		return;
-		}
-
-	for (i = 1; i <= NUM_SYS_STR_REASONS; i++)
-		{
-		ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];
-
-		str->error = (unsigned long)i;
-		if (str->string == NULL)
-			{
-			char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]);
-			char *src = strerror(i);
-			if (src != NULL)
-				{
-				strncpy(*dest, src, sizeof *dest);
-				(*dest)[sizeof *dest - 1] = '\0';
-				str->string = *dest;
-				}
-			}
-		if (str->string == NULL)
-			str->string = "unknown";
-		}
-
-	/* Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL},
-	 * as required by ERR_load_strings. */
-
-	init = 0;
-	
-	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
-	}
-#endif
+static unsigned long get_error_values(int inc,int top,
+					const char **file,int *line,
+					const char **data,int *flags);
 
 #define err_clear_data(p,i) \
 	do { \
@@ -613,68 +143,6 @@
 	(p)->err_line[i]= -1; \
 	} while(0)
 
-static void ERR_STATE_free(ERR_STATE *s)
-	{
-	int i;
-
-	if (s == NULL)
-	    return;
-
-	for (i=0; i<ERR_NUM_ERRORS; i++)
-		{
-		err_clear_data(s,i);
-		}
-	OPENSSL_free(s);
-	}
-
-void ERR_load_ERR_strings(void)
-	{
-	err_fns_check();
-#ifndef OPENSSL_NO_ERR
-	err_load_strings(0,ERR_str_libraries);
-	err_load_strings(0,ERR_str_reasons);
-	err_load_strings(ERR_LIB_SYS,ERR_str_functs);
-	build_SYS_str_reasons();
-	err_load_strings(ERR_LIB_SYS,SYS_str_reasons);
-#endif
-	}
-
-static void err_load_strings(int lib, ERR_STRING_DATA *str)
-	{
-	while (str->error)
-		{
-		if (lib)
-			str->error|=ERR_PACK(lib,0,0);
-		ERRFN(err_set_item)(str);
-		str++;
-		}
-	}
-
-void ERR_load_strings(int lib, ERR_STRING_DATA *str)
-	{
-	ERR_load_ERR_strings();
-	err_load_strings(lib, str);
-	}
-
-void ERR_unload_strings(int lib, ERR_STRING_DATA *str)
-	{
-	while (str->error)
-		{
-		if (lib)
-			str->error|=ERR_PACK(lib,0,0);
-		ERRFN(err_del_item)(str);
-		str++;
-		}
-	}
-
-void ERR_free_strings(void)
-	{
-	err_fns_check();
-	ERRFN(err_del)();
-	}
-
-/********************************************************/
-
 void ERR_put_error(int lib, int func, int reason, const char *file,
 	     int line)
 	{
@@ -829,218 +297,6 @@
 	return ret;
 	}
 
-void ERR_error_string_n(unsigned long e, char *buf, size_t len)
-	{
-	char lsbuf[64], fsbuf[64], rsbuf[64];
-	const char *ls,*fs,*rs;
-	unsigned long l,f,r;
-
-	l=ERR_GET_LIB(e);
-	f=ERR_GET_FUNC(e);
-	r=ERR_GET_REASON(e);
-
-	ls=ERR_lib_error_string(e);
-	fs=ERR_func_error_string(e);
-	rs=ERR_reason_error_string(e);
-
-	if (ls == NULL) 
-		BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l);
-	if (fs == NULL)
-		BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f);
-	if (rs == NULL)
-		BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r);
-
-	BIO_snprintf(buf, len,"error:%08lX:%s:%s:%s", e, ls?ls:lsbuf, 
-		fs?fs:fsbuf, rs?rs:rsbuf);
-	if (strlen(buf) == len-1)
-		{
-		/* output may be truncated; make sure we always have 5 
-		 * colon-separated fields, i.e. 4 colons ... */
-#define NUM_COLONS 4
-		if (len > NUM_COLONS) /* ... if possible */
-			{
-			int i;
-			char *s = buf;
-			
-			for (i = 0; i < NUM_COLONS; i++)
-				{
-				char *colon = strchr(s, ':');
-				if (colon == NULL || colon > &buf[len-1] - NUM_COLONS + i)
-					{
-					/* set colon no. i at last possible position
-					 * (buf[len-1] is the terminating 0)*/
-					colon = &buf[len-1] - NUM_COLONS + i;
-					*colon = ':';
-					}
-				s = colon + 1;
-				}
-			}
-		}
-	}
-
-/* BAD for multi-threading: uses a local buffer if ret == NULL */
-/* ERR_error_string_n should be used instead for ret != NULL
- * as ERR_error_string cannot know how large the buffer is */
-char *ERR_error_string(unsigned long e, char *ret)
-	{
-	static char buf[256];
-
-	if (ret == NULL) ret=buf;
-	ERR_error_string_n(e, ret, 256);
-
-	return ret;
-	}
-
-LHASH *ERR_get_string_table(void)
-	{
-	err_fns_check();
-	return ERRFN(err_get)(0);
-	}
-
-LHASH *ERR_get_err_state_table(void)
-	{
-	err_fns_check();
-	return ERRFN(thread_get)(0);
-	}
-
-void ERR_release_err_state_table(LHASH **hash)
-	{
-	err_fns_check();
-	ERRFN(thread_release)(hash);
-	}
-
-const char *ERR_lib_error_string(unsigned long e)
-	{
-	ERR_STRING_DATA d,*p;
-	unsigned long l;
-
-	err_fns_check();
-	l=ERR_GET_LIB(e);
-	d.error=ERR_PACK(l,0,0);
-	p=ERRFN(err_get_item)(&d);
-	return((p == NULL)?NULL:p->string);
-	}
-
-const char *ERR_func_error_string(unsigned long e)
-	{
-	ERR_STRING_DATA d,*p;
-	unsigned long l,f;
-
-	err_fns_check();
-	l=ERR_GET_LIB(e);
-	f=ERR_GET_FUNC(e);
-	d.error=ERR_PACK(l,f,0);
-	p=ERRFN(err_get_item)(&d);
-	return((p == NULL)?NULL:p->string);
-	}
-
-const char *ERR_reason_error_string(unsigned long e)
-	{
-	ERR_STRING_DATA d,*p=NULL;
-	unsigned long l,r;
-
-	err_fns_check();
-	l=ERR_GET_LIB(e);
-	r=ERR_GET_REASON(e);
-	d.error=ERR_PACK(l,0,r);
-	p=ERRFN(err_get_item)(&d);
-	if (!p)
-		{
-		d.error=ERR_PACK(0,0,r);
-		p=ERRFN(err_get_item)(&d);
-		}
-	return((p == NULL)?NULL:p->string);
-	}
-
-/* static unsigned long err_hash(ERR_STRING_DATA *a) */
-static unsigned long err_hash(const void *a_void)
-	{
-	unsigned long ret,l;
-
-	l=((const ERR_STRING_DATA *)a_void)->error;
-	ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l);
-	return(ret^ret%19*13);
-	}
-
-/* static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b) */
-static int err_cmp(const void *a_void, const void *b_void)
-	{
-	return((int)(((const ERR_STRING_DATA *)a_void)->error -
-			((const ERR_STRING_DATA *)b_void)->error));
-	}
-
-/* static unsigned long pid_hash(ERR_STATE *a) */
-static unsigned long pid_hash(const void *a_void)
-	{
-	return(((const ERR_STATE *)a_void)->pid*13);
-	}
-
-/* static int pid_cmp(ERR_STATE *a, ERR_STATE *b) */
-static int pid_cmp(const void *a_void, const void *b_void)
-	{
-	return((int)((long)((const ERR_STATE *)a_void)->pid -
-			(long)((const ERR_STATE *)b_void)->pid));
-	}
-
-void ERR_remove_state(unsigned long pid)
-	{
-	ERR_STATE tmp;
-
-	err_fns_check();
-	if (pid == 0)
-		pid=(unsigned long)CRYPTO_thread_id();
-	tmp.pid=pid;
-	/* thread_del_item automatically destroys the LHASH if the number of
-	 * items reaches zero. */
-	ERRFN(thread_del_item)(&tmp);
-	}
-
-ERR_STATE *ERR_get_state(void)
-	{
-	static ERR_STATE fallback;
-	ERR_STATE *ret,tmp,*tmpp=NULL;
-	int i;
-	unsigned long pid;
-
-	err_fns_check();
-	pid=(unsigned long)CRYPTO_thread_id();
-	tmp.pid=pid;
-	ret=ERRFN(thread_get_item)(&tmp);
-
-	/* ret == the error state, if NULL, make a new one */
-	if (ret == NULL)
-		{
-		ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE));
-		if (ret == NULL) return(&fallback);
-		ret->pid=pid;
-		ret->top=0;
-		ret->bottom=0;
-		for (i=0; i<ERR_NUM_ERRORS; i++)
-			{
-			ret->err_data[i]=NULL;
-			ret->err_data_flags[i]=0;
-			}
-		tmpp = ERRFN(thread_set_item)(ret);
-		/* To check if insertion failed, do a get. */
-		if (ERRFN(thread_get_item)(ret) != ret)
-			{
-			ERR_STATE_free(ret); /* could not insert it */
-			return(&fallback);
-			}
-		/* If a race occured in this function and we came second, tmpp
-		 * is the first one that we just replaced. */
-		if (tmpp)
-			ERR_STATE_free(tmpp);
-		}
-	return ret;
-	}
-
-int ERR_get_next_error_library(void)
-	{
-	err_fns_check();
-	return ERRFN(get_next_lib)();
-	}
-
 void ERR_set_error_data(char *data, int flags)
 	{
 	ERR_STATE *es;
@@ -1127,3 +383,34 @@
 	es->err_flags[es->top]&=~ERR_FLAG_MARK;
 	return 1;
 	}
+
+#ifdef OPENSSL_FIPS
+
+static ERR_STATE *fget_state(void)
+	{
+	static ERR_STATE fstate;
+	return &fstate;
+	}
+
+ERR_STATE *(*get_state_func)(void) = fget_state;
+void (*remove_state_func)(unsigned long pid);
+
+ERR_STATE *ERR_get_state(void)
+	{
+	return get_state_func();
+	}
+
+void int_ERR_set_state_func(ERR_STATE *(*get_func)(void),
+				void (*remove_func)(unsigned long pid))
+	{
+	get_state_func = get_func;
+	remove_state_func = remove_func;
+	}
+
+void ERR_remove_state(unsigned long pid)
+	{
+	if (remove_state_func)
+		remove_state_func(pid);
+	}
+
+#endif
diff --git a/crypto/err/err.h b/crypto/err/err.h
index bf28fce..dcac415 100644
--- a/crypto/err/err.h
+++ b/crypto/err/err.h
@@ -140,7 +140,9 @@
 #define ERR_LIB_ECDSA		42
 #define ERR_LIB_ECDH		43
 #define ERR_LIB_STORE           44
-#define ERR_LIB_CMS		45
+#define ERR_LIB_FIPS		45
+#define ERR_LIB_CMS		46
+#define ERR_LIB_JPAKE		47
 
 #define ERR_LIB_USER		128
 
@@ -172,7 +174,9 @@
 #define ECDSAerr(f,r)  ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),__FILE__,__LINE__)
 #define ECDHerr(f,r)  ERR_PUT_error(ERR_LIB_ECDH,(f),(r),__FILE__,__LINE__)
 #define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__)
+#define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),__FILE__,__LINE__)
 #define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),__FILE__,__LINE__)
+#define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),__FILE__,__LINE__)
 
 /* Borland C seems too stupid to be able to shift and do longs in
  * the pre-processor :-( */
@@ -304,6 +308,12 @@
 int ERR_set_mark(void);
 int ERR_pop_to_mark(void);
 
+#ifdef OPENSSL_FIPS
+void int_ERR_set_state_func(ERR_STATE *(*get_func)(void),
+				void (*remove_func)(unsigned long pid));
+void int_ERR_lib_init(void);
+#endif
+
 /* Already defined in ossl_typ.h */
 /* typedef struct st_ERR_FNS ERR_FNS; */
 /* An application can use this function and provide the return value to loaded
diff --git a/crypto/err/err_all.c b/crypto/err/err_all.c
index 5d0a985..72c6913 100644
--- a/crypto/err/err_all.c
+++ b/crypto/err/err_all.c
@@ -94,9 +94,16 @@
 #include <openssl/ui.h>
 #include <openssl/ocsp.h>
 #include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 #ifndef OPENSSL_NO_CMS
 #include <openssl/cms.h>
 #endif
+#ifndef OPENSSL_NO_JPAKE
+#include <openssl/jpake.h>
+#endif
 
 void ERR_load_crypto_strings(void)
 	{
@@ -143,8 +150,14 @@
 	ERR_load_OCSP_strings();
 #endif
 	ERR_load_UI_strings();
+#ifdef OPENSSL_FIPS
+	ERR_load_FIPS_strings();
+#endif
 #ifndef OPENSSL_NO_CMS
 	ERR_load_CMS_strings();
 #endif
+#ifndef OPENSSL_NO_JPAKE
+	ERR_load_JPAKE_strings();
+#endif
 #endif
 	}
diff --git a/crypto/err/err_bio.c b/crypto/err/err_bio.c
new file mode 100644
index 0000000..a42f804
--- /dev/null
+++ b/crypto/err/err_bio.c
@@ -0,0 +1,75 @@
+/* crypto/err/err_prn.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+
+static int print_bio(const char *str, size_t len, void *bp)
+	{
+	return BIO_write((BIO *)bp, str, len);
+	}
+void ERR_print_errors(BIO *bp)
+	{
+	ERR_print_errors_cb(print_bio, bp);
+	}
+
+	
diff --git a/crypto/err/err_def.c b/crypto/err/err_def.c
new file mode 100644
index 0000000..7ed3d84
--- /dev/null
+++ b/crypto/err/err_def.c
@@ -0,0 +1,665 @@
+/* crypto/err/err_def.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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).
+ *
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+
+#define err_clear_data(p,i) \
+	do { \
+	if (((p)->err_data[i] != NULL) && \
+		(p)->err_data_flags[i] & ERR_TXT_MALLOCED) \
+		{  \
+		OPENSSL_free((p)->err_data[i]); \
+		(p)->err_data[i]=NULL; \
+		} \
+	(p)->err_data_flags[i]=0; \
+	} while(0)
+
+#define err_clear(p,i) \
+	do { \
+	(p)->err_flags[i]=0; \
+	(p)->err_buffer[i]=0; \
+	err_clear_data(p,i); \
+	(p)->err_file[i]=NULL; \
+	(p)->err_line[i]= -1; \
+	} while(0)
+
+static void err_load_strings(int lib, ERR_STRING_DATA *str);
+
+static void ERR_STATE_free(ERR_STATE *s);
+
+/* Define the predeclared (but externally opaque) "ERR_FNS" type */
+struct st_ERR_FNS
+	{
+	/* Works on the "error_hash" string table */
+	LHASH *(*cb_err_get)(int create);
+	void (*cb_err_del)(void);
+	ERR_STRING_DATA *(*cb_err_get_item)(const ERR_STRING_DATA *);
+	ERR_STRING_DATA *(*cb_err_set_item)(ERR_STRING_DATA *);
+	ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *);
+	/* Works on the "thread_hash" error-state table */
+	LHASH *(*cb_thread_get)(int create);
+	void (*cb_thread_release)(LHASH **hash);
+	ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *);
+	ERR_STATE *(*cb_thread_set_item)(ERR_STATE *);
+	void (*cb_thread_del_item)(const ERR_STATE *);
+	/* Returns the next available error "library" numbers */
+	int (*cb_get_next_lib)(void);
+	};
+
+/* Predeclarations of the "err_defaults" functions */
+static LHASH *int_err_get(int create);
+static void int_err_del(void);
+static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
+static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *);
+static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *);
+static LHASH *int_thread_get(int create);
+static void int_thread_release(LHASH **hash);
+static ERR_STATE *int_thread_get_item(const ERR_STATE *);
+static ERR_STATE *int_thread_set_item(ERR_STATE *);
+static void int_thread_del_item(const ERR_STATE *);
+static int int_err_get_next_lib(void);
+/* The static ERR_FNS table using these defaults functions */
+static const ERR_FNS err_defaults =
+	{
+	int_err_get,
+	int_err_del,
+	int_err_get_item,
+	int_err_set_item,
+	int_err_del_item,
+	int_thread_get,
+	int_thread_release,
+	int_thread_get_item,
+	int_thread_set_item,
+	int_thread_del_item,
+	int_err_get_next_lib
+	};
+
+/* The replacable table of ERR_FNS functions we use at run-time */
+static const ERR_FNS *err_fns = NULL;
+
+/* Eg. rather than using "err_get()", use "ERRFN(err_get)()". */
+#define ERRFN(a) err_fns->cb_##a
+
+/* The internal state used by "err_defaults" - as such, the setting, reading,
+ * creating, and deleting of this data should only be permitted via the
+ * "err_defaults" functions. This way, a linked module can completely defer all
+ * ERR state operation (together with requisite locking) to the implementations
+ * and state in the loading application. */
+static LHASH *int_error_hash = NULL;
+static LHASH *int_thread_hash = NULL;
+static int int_thread_hash_references = 0;
+static int int_err_library_number= ERR_LIB_USER;
+
+/* Internal function that checks whether "err_fns" is set and if not, sets it to
+ * the defaults. */
+static void err_fns_check(void)
+	{
+	if (err_fns) return;
+	
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	if (!err_fns)
+		err_fns = &err_defaults;
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+	}
+
+/* API functions to get or set the underlying ERR functions. */
+
+const ERR_FNS *ERR_get_implementation(void)
+	{
+	err_fns_check();
+	return err_fns;
+	}
+
+int ERR_set_implementation(const ERR_FNS *fns)
+	{
+	int ret = 0;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	/* It's too late if 'err_fns' is non-NULL. BTW: not much point setting
+	 * an error is there?! */
+	if (!err_fns)
+		{
+		err_fns = fns;
+		ret = 1;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+	return ret;
+	}
+
+/* These are the callbacks provided to "lh_new()" when creating the LHASH tables
+ * internal to the "err_defaults" implementation. */
+
+/* static unsigned long err_hash(ERR_STRING_DATA *a); */
+static unsigned long err_hash(const void *a_void);
+/* static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b); */
+static int err_cmp(const void *a_void, const void *b_void);
+/* static unsigned long pid_hash(ERR_STATE *pid); */
+static unsigned long pid_hash(const void *pid_void);
+/* static int pid_cmp(ERR_STATE *a,ERR_STATE *pid); */
+static int pid_cmp(const void *a_void,const void *pid_void);
+
+/* The internal functions used in the "err_defaults" implementation */
+
+static LHASH *int_err_get(int create)
+	{
+	LHASH *ret = NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	if (!int_error_hash && create)
+		{
+		CRYPTO_push_info("int_err_get (err.c)");
+		int_error_hash = lh_new(err_hash, err_cmp);
+		CRYPTO_pop_info();
+		}
+	if (int_error_hash)
+		ret = int_error_hash;
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	return ret;
+	}
+
+static void int_err_del(void)
+	{
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	if (int_error_hash)
+		{
+		lh_free(int_error_hash);
+		int_error_hash = NULL;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+	}
+
+static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d)
+	{
+	ERR_STRING_DATA *p;
+	LHASH *hash;
+
+	err_fns_check();
+	hash = ERRFN(err_get)(0);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
+	p = (ERR_STRING_DATA *)lh_retrieve(hash, d);
+	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+
+	return p;
+	}
+
+static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d)
+	{
+	ERR_STRING_DATA *p;
+	LHASH *hash;
+
+	err_fns_check();
+	hash = ERRFN(err_get)(1);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	p = (ERR_STRING_DATA *)lh_insert(hash, d);
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	return p;
+	}
+
+static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d)
+	{
+	ERR_STRING_DATA *p;
+	LHASH *hash;
+
+	err_fns_check();
+	hash = ERRFN(err_get)(0);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	p = (ERR_STRING_DATA *)lh_delete(hash, d);
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	return p;
+	}
+
+static LHASH *int_thread_get(int create)
+	{
+	LHASH *ret = NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	if (!int_thread_hash && create)
+		{
+		CRYPTO_push_info("int_thread_get (err.c)");
+		int_thread_hash = lh_new(pid_hash, pid_cmp);
+		CRYPTO_pop_info();
+		}
+	if (int_thread_hash)
+		{
+		int_thread_hash_references++;
+		ret = int_thread_hash;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+	return ret;
+	}
+
+static void int_thread_release(LHASH **hash)
+	{
+	int i;
+
+	if (hash == NULL || *hash == NULL)
+		return;
+
+	i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR);
+
+#ifdef REF_PRINT
+	fprintf(stderr,"%4d:%s\n",int_thread_hash_references,"ERR");
+#endif
+	if (i > 0) return;
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"int_thread_release, bad reference count\n");
+		abort(); /* ok */
+		}
+#endif
+	*hash = NULL;
+	}
+
+static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
+	{
+	ERR_STATE *p;
+	LHASH *hash;
+
+	err_fns_check();
+	hash = ERRFN(thread_get)(0);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
+	p = (ERR_STATE *)lh_retrieve(hash, d);
+	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+
+	ERRFN(thread_release)(&hash);
+	return p;
+	}
+
+static ERR_STATE *int_thread_set_item(ERR_STATE *d)
+	{
+	ERR_STATE *p;
+	LHASH *hash;
+
+	err_fns_check();
+	hash = ERRFN(thread_get)(1);
+	if (!hash)
+		return NULL;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	p = (ERR_STATE *)lh_insert(hash, d);
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	ERRFN(thread_release)(&hash);
+	return p;
+	}
+
+static void int_thread_del_item(const ERR_STATE *d)
+	{
+	ERR_STATE *p;
+	LHASH *hash;
+
+	err_fns_check();
+	hash = ERRFN(thread_get)(0);
+	if (!hash)
+		return;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	p = (ERR_STATE *)lh_delete(hash, d);
+	/* make sure we don't leak memory */
+	if (int_thread_hash_references == 1
+		&& int_thread_hash && (lh_num_items(int_thread_hash) == 0))
+		{
+		lh_free(int_thread_hash);
+		int_thread_hash = NULL;
+		}
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	ERRFN(thread_release)(&hash);
+	if (p)
+		ERR_STATE_free(p);
+	}
+
+static int int_err_get_next_lib(void)
+	{
+	int ret;
+
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	ret = int_err_library_number++;
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+
+	return ret;
+	}
+
+static void ERR_STATE_free(ERR_STATE *s)
+	{
+	int i;
+
+	if (s == NULL)
+	    return;
+
+	for (i=0; i<ERR_NUM_ERRORS; i++)
+		{
+		err_clear_data(s,i);
+		}
+	OPENSSL_free(s);
+	}
+
+static void err_load_strings(int lib, ERR_STRING_DATA *str)
+	{
+	while (str->error)
+		{
+		if (lib)
+			str->error|=ERR_PACK(lib,0,0);
+		ERRFN(err_set_item)(str);
+		str++;
+		}
+	}
+
+void ERR_load_strings(int lib, ERR_STRING_DATA *str)
+	{
+	err_fns_check();
+	err_load_strings(lib, str);
+	}
+
+void ERR_unload_strings(int lib, ERR_STRING_DATA *str)
+	{
+	while (str->error)
+		{
+		if (lib)
+			str->error|=ERR_PACK(lib,0,0);
+		ERRFN(err_del_item)(str);
+		str++;
+		}
+	}
+
+void ERR_free_strings(void)
+	{
+	err_fns_check();
+	ERRFN(err_del)();
+	}
+
+LHASH *ERR_get_string_table(void)
+	{
+	err_fns_check();
+	return ERRFN(err_get)(0);
+	}
+
+LHASH *ERR_get_err_state_table(void)
+	{
+	err_fns_check();
+	return ERRFN(thread_get)(0);
+	}
+
+void ERR_release_err_state_table(LHASH **hash)
+	{
+	err_fns_check();
+	ERRFN(thread_release)(hash);
+	}
+
+const char *ERR_lib_error_string(unsigned long e)
+	{
+	ERR_STRING_DATA d,*p;
+	unsigned long l;
+
+	err_fns_check();
+	l=ERR_GET_LIB(e);
+	d.error=ERR_PACK(l,0,0);
+	p=ERRFN(err_get_item)(&d);
+	return((p == NULL)?NULL:p->string);
+	}
+
+const char *ERR_func_error_string(unsigned long e)
+	{
+	ERR_STRING_DATA d,*p;
+	unsigned long l,f;
+
+	err_fns_check();
+	l=ERR_GET_LIB(e);
+	f=ERR_GET_FUNC(e);
+	d.error=ERR_PACK(l,f,0);
+	p=ERRFN(err_get_item)(&d);
+	return((p == NULL)?NULL:p->string);
+	}
+
+const char *ERR_reason_error_string(unsigned long e)
+	{
+	ERR_STRING_DATA d,*p=NULL;
+	unsigned long l,r;
+
+	err_fns_check();
+	l=ERR_GET_LIB(e);
+	r=ERR_GET_REASON(e);
+	d.error=ERR_PACK(l,0,r);
+	p=ERRFN(err_get_item)(&d);
+	if (!p)
+		{
+		d.error=ERR_PACK(0,0,r);
+		p=ERRFN(err_get_item)(&d);
+		}
+	return((p == NULL)?NULL:p->string);
+	}
+
+/* static unsigned long err_hash(ERR_STRING_DATA *a) */
+static unsigned long err_hash(const void *a_void)
+	{
+	unsigned long ret,l;
+
+	l=((const ERR_STRING_DATA *)a_void)->error;
+	ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l);
+	return(ret^ret%19*13);
+	}
+
+/* static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b) */
+static int err_cmp(const void *a_void, const void *b_void)
+	{
+	return((int)(((const ERR_STRING_DATA *)a_void)->error -
+			((const ERR_STRING_DATA *)b_void)->error));
+	}
+
+/* static unsigned long pid_hash(ERR_STATE *a) */
+static unsigned long pid_hash(const void *a_void)
+	{
+	return(((const ERR_STATE *)a_void)->pid*13);
+	}
+
+/* static int pid_cmp(ERR_STATE *a, ERR_STATE *b) */
+static int pid_cmp(const void *a_void, const void *b_void)
+	{
+	return((int)((long)((const ERR_STATE *)a_void)->pid -
+			(long)((const ERR_STATE *)b_void)->pid));
+	}
+#ifdef OPENSSL_FIPS
+static void int_err_remove_state(unsigned long pid)
+#else
+void ERR_remove_state(unsigned long pid)
+#endif
+	{
+	ERR_STATE tmp;
+
+	err_fns_check();
+	if (pid == 0)
+		pid=(unsigned long)CRYPTO_thread_id();
+	tmp.pid=pid;
+	/* thread_del_item automatically destroys the LHASH if the number of
+	 * items reaches zero. */
+	ERRFN(thread_del_item)(&tmp);
+	}
+
+#ifdef OPENSSL_FIPS
+	static ERR_STATE *int_err_get_state(void)
+#else
+ERR_STATE *ERR_get_state(void)
+#endif
+	{
+	static ERR_STATE fallback;
+	ERR_STATE *ret,tmp,*tmpp=NULL;
+	int i;
+	unsigned long pid;
+
+	err_fns_check();
+	pid=(unsigned long)CRYPTO_thread_id();
+	tmp.pid=pid;
+	ret=ERRFN(thread_get_item)(&tmp);
+
+	/* ret == the error state, if NULL, make a new one */
+	if (ret == NULL)
+		{
+		ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE));
+		if (ret == NULL) return(&fallback);
+		ret->pid=pid;
+		ret->top=0;
+		ret->bottom=0;
+		for (i=0; i<ERR_NUM_ERRORS; i++)
+			{
+			ret->err_data[i]=NULL;
+			ret->err_data_flags[i]=0;
+			}
+		tmpp = ERRFN(thread_set_item)(ret);
+		/* To check if insertion failed, do a get. */
+		if (ERRFN(thread_get_item)(ret) != ret)
+			{
+			ERR_STATE_free(ret); /* could not insert it */
+			return(&fallback);
+			}
+		/* If a race occured in this function and we came second, tmpp
+		 * is the first one that we just replaced. */
+		if (tmpp)
+			ERR_STATE_free(tmpp);
+		}
+	return ret;
+	}
+
+#ifdef OPENSSL_FIPS
+void int_ERR_lib_init(void)
+	{
+	int_ERR_set_state_func(int_err_get_state, int_err_remove_state);
+	}
+#endif
+
+int ERR_get_next_error_library(void)
+	{
+	err_fns_check();
+	return ERRFN(get_next_lib)();
+	}
diff --git a/crypto/err/err_prn.c b/crypto/err/err_prn.c
index 2224a90..4cdf342 100644
--- a/crypto/err/err_prn.c
+++ b/crypto/err/err_prn.c
@@ -86,12 +86,7 @@
 #ifndef OPENSSL_NO_FP_API
 static int print_fp(const char *str, size_t len, void *fp)
 	{
-	BIO bio;
-
-	BIO_set(&bio,BIO_s_file());
-	BIO_set_fp(&bio,fp,BIO_NOCLOSE);
-
-	return BIO_printf(&bio, "%s", str);
+	return fwrite(str, 1, len, fp);
 	}
 void ERR_print_errors_fp(FILE *fp)
 	{
@@ -99,13 +94,64 @@
 	}
 #endif
 
-static int print_bio(const char *str, size_t len, void *bp)
+void ERR_error_string_n(unsigned long e, char *buf, size_t len)
 	{
-	return BIO_write((BIO *)bp, str, len);
-	}
-void ERR_print_errors(BIO *bp)
-	{
-	ERR_print_errors_cb(print_bio, bp);
+	char lsbuf[64], fsbuf[64], rsbuf[64];
+	const char *ls,*fs,*rs;
+	unsigned long l,f,r;
+
+	l=ERR_GET_LIB(e);
+	f=ERR_GET_FUNC(e);
+	r=ERR_GET_REASON(e);
+
+	ls=ERR_lib_error_string(e);
+	fs=ERR_func_error_string(e);
+	rs=ERR_reason_error_string(e);
+
+	if (ls == NULL) 
+		BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l);
+	if (fs == NULL)
+		BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f);
+	if (rs == NULL)
+		BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r);
+
+	BIO_snprintf(buf, len,"error:%08lX:%s:%s:%s", e, ls?ls:lsbuf, 
+		fs?fs:fsbuf, rs?rs:rsbuf);
+	if (strlen(buf) == len-1)
+		{
+		/* output may be truncated; make sure we always have 5 
+		 * colon-separated fields, i.e. 4 colons ... */
+#define NUM_COLONS 4
+		if (len > NUM_COLONS) /* ... if possible */
+			{
+			int i;
+			char *s = buf;
+			
+			for (i = 0; i < NUM_COLONS; i++)
+				{
+				char *colon = strchr(s, ':');
+				if (colon == NULL || colon > &buf[len-1] - NUM_COLONS + i)
+					{
+					/* set colon no. i at last possible position
+					 * (buf[len-1] is the terminating 0)*/
+					colon = &buf[len-1] - NUM_COLONS + i;
+					*colon = ':';
+					}
+				s = colon + 1;
+				}
+			}
+		}
 	}
 
-	
+/* BAD for multi-threading: uses a local buffer if ret == NULL */
+/* ERR_error_string_n should be used instead for ret != NULL
+ * as ERR_error_string cannot know how large the buffer is */
+char *ERR_error_string(unsigned long e, char *ret)
+	{
+	static char buf[256];
+
+	if (ret == NULL) ret=buf;
+	ERR_error_string_n(e, ret, 256);
+
+	return ret;
+	}
diff --git a/crypto/err/err_str.c b/crypto/err/err_str.c
new file mode 100644
index 0000000..d390408
--- /dev/null
+++ b/crypto/err/err_str.c
@@ -0,0 +1,295 @@
+/* crypto/err/err_str.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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).
+ *
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+
+#ifndef OPENSSL_NO_ERR
+static ERR_STRING_DATA ERR_str_libraries[]=
+	{
+{ERR_PACK(ERR_LIB_NONE,0,0)		,"unknown library"},
+{ERR_PACK(ERR_LIB_SYS,0,0)		,"system library"},
+{ERR_PACK(ERR_LIB_BN,0,0)		,"bignum routines"},
+{ERR_PACK(ERR_LIB_RSA,0,0)		,"rsa routines"},
+{ERR_PACK(ERR_LIB_DH,0,0)		,"Diffie-Hellman routines"},
+{ERR_PACK(ERR_LIB_EVP,0,0)		,"digital envelope routines"},
+{ERR_PACK(ERR_LIB_BUF,0,0)		,"memory buffer routines"},
+{ERR_PACK(ERR_LIB_OBJ,0,0)		,"object identifier routines"},
+{ERR_PACK(ERR_LIB_PEM,0,0)		,"PEM routines"},
+{ERR_PACK(ERR_LIB_DSA,0,0)		,"dsa routines"},
+{ERR_PACK(ERR_LIB_X509,0,0)		,"x509 certificate routines"},
+{ERR_PACK(ERR_LIB_ASN1,0,0)		,"asn1 encoding routines"},
+{ERR_PACK(ERR_LIB_CONF,0,0)		,"configuration file routines"},
+{ERR_PACK(ERR_LIB_CRYPTO,0,0)		,"common libcrypto routines"},
+{ERR_PACK(ERR_LIB_EC,0,0)		,"elliptic curve routines"},
+{ERR_PACK(ERR_LIB_SSL,0,0)		,"SSL routines"},
+{ERR_PACK(ERR_LIB_BIO,0,0)		,"BIO routines"},
+{ERR_PACK(ERR_LIB_PKCS7,0,0)		,"PKCS7 routines"},
+{ERR_PACK(ERR_LIB_X509V3,0,0)		,"X509 V3 routines"},
+{ERR_PACK(ERR_LIB_PKCS12,0,0)		,"PKCS12 routines"},
+{ERR_PACK(ERR_LIB_RAND,0,0)		,"random number generator"},
+{ERR_PACK(ERR_LIB_DSO,0,0)		,"DSO support routines"},
+{ERR_PACK(ERR_LIB_ENGINE,0,0)		,"engine routines"},
+{ERR_PACK(ERR_LIB_OCSP,0,0)		,"OCSP routines"},
+{ERR_PACK(ERR_LIB_FIPS,0,0)		,"FIPS routines"},
+{ERR_PACK(ERR_LIB_CMS,0,0)		,"CMS routines"},
+{ERR_PACK(ERR_LIB_JPAKE,0,0)		,"JPAKE routines"},
+{0,NULL},
+	};
+
+static ERR_STRING_DATA ERR_str_functs[]=
+	{
+	{ERR_PACK(0,SYS_F_FOPEN,0),     	"fopen"},
+	{ERR_PACK(0,SYS_F_CONNECT,0),		"connect"},
+	{ERR_PACK(0,SYS_F_GETSERVBYNAME,0),	"getservbyname"},
+	{ERR_PACK(0,SYS_F_SOCKET,0),		"socket"}, 
+	{ERR_PACK(0,SYS_F_IOCTLSOCKET,0),	"ioctlsocket"},
+	{ERR_PACK(0,SYS_F_BIND,0),		"bind"},
+	{ERR_PACK(0,SYS_F_LISTEN,0),		"listen"},
+	{ERR_PACK(0,SYS_F_ACCEPT,0),		"accept"},
+#ifdef OPENSSL_SYS_WINDOWS
+	{ERR_PACK(0,SYS_F_WSASTARTUP,0),	"WSAstartup"},
+#endif
+	{ERR_PACK(0,SYS_F_OPENDIR,0),		"opendir"},
+	{ERR_PACK(0,SYS_F_FREAD,0),		"fread"},
+	{0,NULL},
+	};
+
+static ERR_STRING_DATA ERR_str_reasons[]=
+	{
+{ERR_R_SYS_LIB				,"system lib"},
+{ERR_R_BN_LIB				,"BN lib"},
+{ERR_R_RSA_LIB				,"RSA lib"},
+{ERR_R_DH_LIB				,"DH lib"},
+{ERR_R_EVP_LIB				,"EVP lib"},
+{ERR_R_BUF_LIB				,"BUF lib"},
+{ERR_R_OBJ_LIB				,"OBJ lib"},
+{ERR_R_PEM_LIB				,"PEM lib"},
+{ERR_R_DSA_LIB				,"DSA lib"},
+{ERR_R_X509_LIB				,"X509 lib"},
+{ERR_R_ASN1_LIB				,"ASN1 lib"},
+{ERR_R_CONF_LIB				,"CONF lib"},
+{ERR_R_CRYPTO_LIB			,"CRYPTO lib"},
+{ERR_R_EC_LIB				,"EC lib"},
+{ERR_R_SSL_LIB				,"SSL lib"},
+{ERR_R_BIO_LIB				,"BIO lib"},
+{ERR_R_PKCS7_LIB			,"PKCS7 lib"},
+{ERR_R_X509V3_LIB			,"X509V3 lib"},
+{ERR_R_PKCS12_LIB			,"PKCS12 lib"},
+{ERR_R_RAND_LIB				,"RAND lib"},
+{ERR_R_DSO_LIB				,"DSO lib"},
+{ERR_R_ENGINE_LIB			,"ENGINE lib"},
+{ERR_R_OCSP_LIB				,"OCSP lib"},
+
+{ERR_R_NESTED_ASN1_ERROR		,"nested asn1 error"},
+{ERR_R_BAD_ASN1_OBJECT_HEADER		,"bad asn1 object header"},
+{ERR_R_BAD_GET_ASN1_OBJECT_CALL		,"bad get asn1 object call"},
+{ERR_R_EXPECTING_AN_ASN1_SEQUENCE	,"expecting an asn1 sequence"},
+{ERR_R_ASN1_LENGTH_MISMATCH		,"asn1 length mismatch"},
+{ERR_R_MISSING_ASN1_EOS			,"missing asn1 eos"},
+
+{ERR_R_FATAL                            ,"fatal"},
+{ERR_R_MALLOC_FAILURE			,"malloc failure"},
+{ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED	,"called a function you should not call"},
+{ERR_R_PASSED_NULL_PARAMETER		,"passed a null parameter"},
+{ERR_R_INTERNAL_ERROR			,"internal error"},
+{ERR_R_DISABLED				,"called a function that was disabled at compile-time"},
+
+{0,NULL},
+	};
+#endif
+
+#ifndef OPENSSL_NO_ERR
+#define NUM_SYS_STR_REASONS 127
+#define LEN_SYS_STR_REASON 32
+
+static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
+/* SYS_str_reasons is filled with copies of strerror() results at
+ * initialization.
+ * 'errno' values up to 127 should cover all usual errors,
+ * others will be displayed numerically by ERR_error_string.
+ * It is crucial that we have something for each reason code
+ * that occurs in ERR_str_reasons, or bogus reason strings
+ * will be returned for SYSerr, which always gets an errno
+ * value and never one of those 'standard' reason codes. */
+
+static void build_SYS_str_reasons(void)
+	{
+	/* OPENSSL_malloc cannot be used here, use static storage instead */
+	static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
+	int i;
+	static int init = 1;
+
+	CRYPTO_r_lock(CRYPTO_LOCK_ERR);
+	if (!init)
+		{
+		CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+		return;
+		}
+	
+	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+	if (!init)
+		{
+		CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+		return;
+		}
+
+	for (i = 1; i <= NUM_SYS_STR_REASONS; i++)
+		{
+		ERR_STRING_DATA *str = &SYS_str_reasons[i - 1];
+
+		str->error = (unsigned long)i;
+		if (str->string == NULL)
+			{
+			char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]);
+			char *src = strerror(i);
+			if (src != NULL)
+				{
+				strncpy(*dest, src, sizeof *dest);
+				(*dest)[sizeof *dest - 1] = '\0';
+				str->string = *dest;
+				}
+			}
+		if (str->string == NULL)
+			str->string = "unknown";
+		}
+
+	/* Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL},
+	 * as required by ERR_load_strings. */
+
+	init = 0;
+	
+	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+	}
+#endif
+
+void ERR_load_ERR_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+	if (ERR_func_error_string(ERR_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,ERR_str_libraries);
+		ERR_load_strings(0,ERR_str_reasons);
+		ERR_load_strings(ERR_LIB_SYS,ERR_str_functs);
+		build_SYS_str_reasons();
+		ERR_load_strings(ERR_LIB_SYS,SYS_str_reasons);
+		}
+#endif
+	}
+
diff --git a/crypto/err/openssl.ec b/crypto/err/openssl.ec
index 1938f08..8688266 100644
--- a/crypto/err/openssl.ec
+++ b/crypto/err/openssl.ec
@@ -31,7 +31,9 @@
 L ECDSA		crypto/ecdsa/ecdsa.h		crypto/ecdsa/ecs_err.c
 L ECDH		crypto/ecdh/ecdh.h		crypto/ecdh/ech_err.c
 L STORE		crypto/store/store.h		crypto/store/str_err.c
+L FIPS		fips/fips.h			crypto/fips_err.h
 L CMS		crypto/cms/cms.h		crypto/cms/cms_err.c
+L JPAKE		crypto/jpake/jpake.h		crypto/jpake/jpake_err.c
 
 # additional header files to be scanned for function names
 L NONE		crypto/x509/x509_vfy.h		NONE
diff --git a/crypto/evp/Makefile b/crypto/evp/Makefile
index 8f2555c..c204f84 100644
--- a/crypto/evp/Makefile
+++ b/crypto/evp/Makefile
@@ -18,10 +18,10 @@
 APPS=
 
 LIB=$(TOP)/libcrypto.a
-LIBSRC= encode.c digest.c evp_enc.c evp_key.c evp_acnf.c \
+LIBSRC= encode.c digest.c dig_eng.c evp_enc.c evp_key.c evp_acnf.c evp_cnf.c \
 	e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\
 	e_rc4.c e_aes.c names.c e_seed.c \
-	e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c \
+	e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c enc_min.c \
 	m_null.c m_md2.c m_md4.c m_md5.c m_sha.c m_sha1.c \
 	m_dss.c m_dss1.c m_mdc2.c m_ripemd.c m_ecdsa.c\
 	p_open.c p_seal.c p_sign.c p_verify.c p_lib.c p_enc.c p_dec.c \
@@ -30,10 +30,10 @@
 	evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c \
 	e_old.c
 
-LIBOBJ=	encode.o digest.o evp_enc.o evp_key.o evp_acnf.o \
+LIBOBJ=	encode.o digest.o dig_eng.o evp_enc.o evp_key.o evp_acnf.o evp_cnf.o \
 	e_des.o e_bf.o e_idea.o e_des3.o e_camellia.o\
 	e_rc4.o e_aes.o names.o e_seed.o \
-	e_xcbc_d.o e_rc2.o e_cast.o e_rc5.o \
+	e_xcbc_d.o e_rc2.o e_cast.o e_rc5.o enc_min.o \
 	m_null.o m_md2.o m_md4.o m_md5.o m_sha.o m_sha1.o \
 	m_dss.o m_dss1.o m_mdc2.o m_ripemd.o m_ecdsa.o\
 	p_open.o p_seal.o p_sign.o p_verify.o p_lib.o p_enc.o p_dec.o \
@@ -55,7 +55,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -101,169 +101,201 @@
 bio_b64.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 bio_b64.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 bio_b64.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-bio_b64.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-bio_b64.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-bio_b64.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bio_b64.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bio_b64.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_b64.c
+bio_b64.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+bio_b64.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+bio_b64.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+bio_b64.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+bio_b64.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+bio_b64.o: ../cryptlib.h bio_b64.c
 bio_enc.o: ../../e_os.h ../../include/openssl/asn1.h
 bio_enc.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 bio_enc.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 bio_enc.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-bio_enc.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-bio_enc.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-bio_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-bio_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bio_enc.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_enc.c
+bio_enc.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+bio_enc.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+bio_enc.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+bio_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+bio_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+bio_enc.o: ../cryptlib.h bio_enc.c
 bio_md.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 bio_md.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bio_md.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bio_md.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-bio_md.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-bio_md.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-bio_md.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-bio_md.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-bio_md.o: ../cryptlib.h bio_md.c
+bio_md.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+bio_md.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+bio_md.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+bio_md.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bio_md.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+bio_md.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_md.c
 bio_ok.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 bio_ok.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 bio_ok.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-bio_ok.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-bio_ok.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-bio_ok.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-bio_ok.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-bio_ok.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-bio_ok.o: ../../include/openssl/symhacks.h ../cryptlib.h bio_ok.c
+bio_ok.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+bio_ok.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+bio_ok.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+bio_ok.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+bio_ok.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+bio_ok.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+bio_ok.o: ../cryptlib.h bio_ok.c
 c_all.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 c_all.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-c_all.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-c_all.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+c_all.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+c_all.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+c_all.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+c_all.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
 c_all.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
 c_all.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 c_all.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-c_all.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-c_all.o: ../../include/openssl/symhacks.h ../cryptlib.h c_all.c
+c_all.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+c_all.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+c_all.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+c_all.o: ../../include/openssl/x509_vfy.h ../cryptlib.h c_all.c
 c_allc.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 c_allc.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 c_allc.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 c_allc.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 c_allc.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-c_allc.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-c_allc.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-c_allc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-c_allc.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
-c_allc.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-c_allc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-c_allc.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-c_allc.o: ../cryptlib.h c_allc.c
+c_allc.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+c_allc.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+c_allc.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+c_allc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
+c_allc.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+c_allc.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+c_allc.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+c_allc.o: ../../include/openssl/x509_vfy.h ../cryptlib.h c_allc.c
 c_alld.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 c_alld.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 c_alld.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 c_alld.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 c_alld.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-c_alld.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-c_alld.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-c_alld.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-c_alld.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
-c_alld.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-c_alld.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-c_alld.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-c_alld.o: ../cryptlib.h c_alld.c
+c_alld.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+c_alld.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+c_alld.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+c_alld.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
+c_alld.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+c_alld.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+c_alld.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+c_alld.o: ../../include/openssl/x509_vfy.h ../cryptlib.h c_alld.c
+dig_eng.o: ../../e_os.h ../../include/openssl/asn1.h
+dig_eng.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+dig_eng.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+dig_eng.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+dig_eng.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+dig_eng.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+dig_eng.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+dig_eng.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+dig_eng.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+dig_eng.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+dig_eng.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+dig_eng.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+dig_eng.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+dig_eng.o: ../cryptlib.h dig_eng.c evp_locl.h
 digest.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 digest.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-digest.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-digest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+digest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+digest.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+digest.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+digest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
 digest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
 digest.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 digest.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-digest.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-digest.o: ../../include/openssl/symhacks.h ../cryptlib.h digest.c
+digest.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+digest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+digest.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+digest.o: ../../include/openssl/x509_vfy.h ../cryptlib.h digest.c evp_locl.h
 e_aes.o: ../../include/openssl/aes.h ../../include/openssl/asn1.h
 e_aes.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
 e_aes.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-e_aes.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-e_aes.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-e_aes.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-e_aes.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-e_aes.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h e_aes.c
-e_aes.o: evp_locl.h
+e_aes.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+e_aes.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+e_aes.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+e_aes.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+e_aes.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+e_aes.o: ../../include/openssl/symhacks.h e_aes.c evp_locl.h
 e_bf.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 e_bf.o: ../../include/openssl/blowfish.h ../../include/openssl/buffer.h
 e_bf.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 e_bf.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-e_bf.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-e_bf.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-e_bf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-e_bf.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-e_bf.o: ../../include/openssl/symhacks.h ../cryptlib.h e_bf.c evp_locl.h
+e_bf.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+e_bf.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+e_bf.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+e_bf.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+e_bf.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+e_bf.o: ../cryptlib.h e_bf.c evp_locl.h
 e_camellia.o: ../../include/openssl/opensslconf.h e_camellia.c
 e_cast.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 e_cast.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h
 e_cast.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 e_cast.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-e_cast.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-e_cast.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-e_cast.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-e_cast.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-e_cast.o: ../../include/openssl/symhacks.h ../cryptlib.h e_cast.c evp_locl.h
+e_cast.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+e_cast.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+e_cast.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+e_cast.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+e_cast.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+e_cast.o: ../cryptlib.h e_cast.c evp_locl.h
 e_des.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 e_des.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 e_des.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
 e_des.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-e_des.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-e_des.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-e_des.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-e_des.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-e_des.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-e_des.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
-e_des.o: ../../include/openssl/ui_compat.h ../cryptlib.h e_des.c evp_locl.h
+e_des.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+e_des.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+e_des.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+e_des.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+e_des.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+e_des.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+e_des.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+e_des.o: ../cryptlib.h e_des.c evp_locl.h
 e_des3.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 e_des3.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 e_des3.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
 e_des3.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-e_des3.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-e_des3.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-e_des3.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-e_des3.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-e_des3.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-e_des3.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
-e_des3.o: ../../include/openssl/ui_compat.h ../cryptlib.h e_des3.c evp_locl.h
+e_des3.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+e_des3.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+e_des3.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+e_des3.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+e_des3.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+e_des3.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+e_des3.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+e_des3.o: ../cryptlib.h e_des3.c evp_locl.h
 e_idea.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 e_idea.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 e_idea.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-e_idea.o: ../../include/openssl/evp.h ../../include/openssl/idea.h
-e_idea.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-e_idea.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-e_idea.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-e_idea.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-e_idea.o: ../../include/openssl/symhacks.h ../cryptlib.h e_idea.c evp_locl.h
+e_idea.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+e_idea.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h
+e_idea.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+e_idea.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+e_idea.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+e_idea.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+e_idea.o: ../cryptlib.h e_idea.c evp_locl.h
 e_null.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 e_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 e_null.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-e_null.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-e_null.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-e_null.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-e_null.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-e_null.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-e_null.o: ../cryptlib.h e_null.c
+e_null.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+e_null.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+e_null.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+e_null.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+e_null.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+e_null.o: ../../include/openssl/symhacks.h ../cryptlib.h e_null.c
 e_old.o: e_old.c
 e_rc2.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 e_rc2.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 e_rc2.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-e_rc2.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-e_rc2.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-e_rc2.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-e_rc2.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rc2.h
-e_rc2.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-e_rc2.o: ../../include/openssl/symhacks.h ../cryptlib.h e_rc2.c evp_locl.h
+e_rc2.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+e_rc2.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+e_rc2.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+e_rc2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+e_rc2.o: ../../include/openssl/rc2.h ../../include/openssl/safestack.h
+e_rc2.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+e_rc2.o: ../cryptlib.h e_rc2.c evp_locl.h
 e_rc4.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 e_rc4.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 e_rc4.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-e_rc4.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-e_rc4.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-e_rc4.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-e_rc4.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rc4.h
-e_rc4.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-e_rc4.o: ../../include/openssl/symhacks.h ../cryptlib.h e_rc4.c
+e_rc4.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+e_rc4.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+e_rc4.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+e_rc4.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+e_rc4.o: ../../include/openssl/rc4.h ../../include/openssl/safestack.h
+e_rc4.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+e_rc4.o: ../cryptlib.h e_rc4.c evp_locl.h
 e_rc5.o: ../../e_os.h ../../include/openssl/bio.h
 e_rc5.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 e_rc5.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
@@ -274,103 +306,141 @@
 e_seed.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 e_seed.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 e_seed.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-e_seed.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-e_seed.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-e_seed.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-e_seed.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-e_seed.o: ../../include/openssl/symhacks.h e_seed.c
+e_seed.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+e_seed.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+e_seed.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+e_seed.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+e_seed.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+e_seed.o: e_seed.c
 e_xcbc_d.o: ../../e_os.h ../../include/openssl/asn1.h
 e_xcbc_d.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 e_xcbc_d.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
 e_xcbc_d.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
 e_xcbc_d.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-e_xcbc_d.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-e_xcbc_d.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+e_xcbc_d.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+e_xcbc_d.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+e_xcbc_d.o: ../../include/openssl/opensslconf.h
 e_xcbc_d.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 e_xcbc_d.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 e_xcbc_d.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
 e_xcbc_d.o: ../../include/openssl/ui_compat.h ../cryptlib.h e_xcbc_d.c
+enc_min.o: ../../e_os.h ../../include/openssl/asn1.h
+enc_min.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+enc_min.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+enc_min.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+enc_min.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+enc_min.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+enc_min.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+enc_min.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+enc_min.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+enc_min.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+enc_min.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+enc_min.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+enc_min.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+enc_min.o: ../../include/openssl/x509_vfy.h ../cryptlib.h enc_min.c evp_locl.h
 encode.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 encode.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 encode.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-encode.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-encode.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-encode.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-encode.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-encode.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-encode.o: ../cryptlib.h encode.c
+encode.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+encode.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+encode.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+encode.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+encode.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+encode.o: ../../include/openssl/symhacks.h ../cryptlib.h encode.c
 evp_acnf.o: ../../e_os.h ../../include/openssl/asn1.h
 evp_acnf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 evp_acnf.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
 evp_acnf.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-evp_acnf.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-evp_acnf.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-evp_acnf.o: ../../include/openssl/opensslconf.h
+evp_acnf.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+evp_acnf.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+evp_acnf.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 evp_acnf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 evp_acnf.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 evp_acnf.o: ../../include/openssl/symhacks.h ../cryptlib.h evp_acnf.c
+evp_cnf.o: ../../e_os.h ../../include/openssl/asn1.h
+evp_cnf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+evp_cnf.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+evp_cnf.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
+evp_cnf.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+evp_cnf.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+evp_cnf.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+evp_cnf.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+evp_cnf.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+evp_cnf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+evp_cnf.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+evp_cnf.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+evp_cnf.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+evp_cnf.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+evp_cnf.o: ../cryptlib.h evp_cnf.c
 evp_enc.o: ../../e_os.h ../../include/openssl/asn1.h
 evp_enc.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 evp_enc.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-evp_enc.o: ../../include/openssl/engine.h ../../include/openssl/err.h
-evp_enc.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+evp_enc.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+evp_enc.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+evp_enc.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+evp_enc.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
 evp_enc.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 evp_enc.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-evp_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-evp_enc.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-evp_enc.o: ../../include/openssl/symhacks.h ../cryptlib.h evp_enc.c evp_locl.h
+evp_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+evp_enc.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+evp_enc.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+evp_enc.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+evp_enc.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_enc.c evp_locl.h
 evp_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 evp_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 evp_err.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-evp_err.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-evp_err.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-evp_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-evp_err.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-evp_err.o: ../../include/openssl/symhacks.h evp_err.c
+evp_err.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+evp_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+evp_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+evp_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+evp_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+evp_err.o: evp_err.c
 evp_key.o: ../../e_os.h ../../include/openssl/asn1.h
 evp_key.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 evp_key.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 evp_key.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 evp_key.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-evp_key.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-evp_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-evp_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-evp_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-evp_key.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-evp_key.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-evp_key.o: ../../include/openssl/ui.h ../../include/openssl/x509.h
-evp_key.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_key.c
+evp_key.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+evp_key.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+evp_key.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+evp_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+evp_key.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+evp_key.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+evp_key.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+evp_key.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+evp_key.o: ../cryptlib.h evp_key.c
 evp_lib.o: ../../e_os.h ../../include/openssl/asn1.h
 evp_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 evp_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 evp_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-evp_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-evp_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-evp_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-evp_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-evp_lib.o: ../../include/openssl/symhacks.h ../cryptlib.h evp_lib.c
+evp_lib.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+evp_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+evp_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+evp_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+evp_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+evp_lib.o: ../cryptlib.h evp_lib.c
 evp_pbe.o: ../../e_os.h ../../include/openssl/asn1.h
 evp_pbe.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 evp_pbe.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 evp_pbe.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 evp_pbe.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-evp_pbe.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-evp_pbe.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-evp_pbe.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-evp_pbe.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-evp_pbe.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-evp_pbe.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-evp_pbe.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-evp_pbe.o: ../cryptlib.h evp_pbe.c
+evp_pbe.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+evp_pbe.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+evp_pbe.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+evp_pbe.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+evp_pbe.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+evp_pbe.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+evp_pbe.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+evp_pbe.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_pbe.c
 evp_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
 evp_pkey.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 evp_pkey.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 evp_pkey.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
 evp_pkey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 evp_pkey.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-evp_pkey.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-evp_pkey.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-evp_pkey.o: ../../include/openssl/opensslconf.h
+evp_pkey.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+evp_pkey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+evp_pkey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 evp_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 evp_pkey.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
 evp_pkey.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
@@ -382,106 +452,110 @@
 m_dss.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
 m_dss.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 m_dss.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-m_dss.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-m_dss.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-m_dss.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-m_dss.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-m_dss.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-m_dss.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-m_dss.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-m_dss.o: ../cryptlib.h m_dss.c
+m_dss.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+m_dss.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+m_dss.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+m_dss.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+m_dss.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+m_dss.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+m_dss.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+m_dss.o: ../../include/openssl/x509_vfy.h ../cryptlib.h m_dss.c
 m_dss1.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 m_dss1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 m_dss1.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
 m_dss1.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 m_dss1.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-m_dss1.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-m_dss1.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-m_dss1.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-m_dss1.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-m_dss1.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-m_dss1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-m_dss1.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-m_dss1.o: ../cryptlib.h m_dss1.c
+m_dss1.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+m_dss1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+m_dss1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+m_dss1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+m_dss1.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+m_dss1.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+m_dss1.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+m_dss1.o: ../../include/openssl/x509_vfy.h ../cryptlib.h m_dss1.c
 m_ecdsa.o: ../../e_os.h ../../include/openssl/asn1.h
 m_ecdsa.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 m_ecdsa.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 m_ecdsa.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 m_ecdsa.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-m_ecdsa.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-m_ecdsa.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-m_ecdsa.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-m_ecdsa.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-m_ecdsa.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-m_ecdsa.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-m_ecdsa.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-m_ecdsa.o: ../cryptlib.h m_ecdsa.c
+m_ecdsa.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+m_ecdsa.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+m_ecdsa.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+m_ecdsa.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+m_ecdsa.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+m_ecdsa.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+m_ecdsa.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+m_ecdsa.o: ../../include/openssl/x509_vfy.h ../cryptlib.h m_ecdsa.c
 m_md2.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 m_md2.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 m_md2.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 m_md2.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 m_md2.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-m_md2.o: ../../include/openssl/lhash.h ../../include/openssl/md2.h
-m_md2.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-m_md2.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-m_md2.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-m_md2.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-m_md2.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-m_md2.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-m_md2.o: ../../include/openssl/x509_vfy.h ../cryptlib.h m_md2.c
+m_md2.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+m_md2.o: ../../include/openssl/md2.h ../../include/openssl/obj_mac.h
+m_md2.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+m_md2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+m_md2.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+m_md2.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+m_md2.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+m_md2.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+m_md2.o: ../cryptlib.h evp_locl.h m_md2.c
 m_md4.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 m_md4.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 m_md4.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 m_md4.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 m_md4.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-m_md4.o: ../../include/openssl/lhash.h ../../include/openssl/md4.h
-m_md4.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-m_md4.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-m_md4.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-m_md4.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-m_md4.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-m_md4.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-m_md4.o: ../../include/openssl/x509_vfy.h ../cryptlib.h m_md4.c
+m_md4.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+m_md4.o: ../../include/openssl/md4.h ../../include/openssl/obj_mac.h
+m_md4.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+m_md4.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+m_md4.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+m_md4.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+m_md4.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+m_md4.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+m_md4.o: ../cryptlib.h evp_locl.h m_md4.c
 m_md5.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 m_md5.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 m_md5.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 m_md5.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 m_md5.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-m_md5.o: ../../include/openssl/lhash.h ../../include/openssl/md5.h
-m_md5.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-m_md5.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-m_md5.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-m_md5.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-m_md5.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-m_md5.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-m_md5.o: ../../include/openssl/x509_vfy.h ../cryptlib.h m_md5.c
+m_md5.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+m_md5.o: ../../include/openssl/md5.h ../../include/openssl/obj_mac.h
+m_md5.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+m_md5.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+m_md5.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+m_md5.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+m_md5.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+m_md5.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+m_md5.o: ../cryptlib.h evp_locl.h m_md5.c
 m_mdc2.o: ../../e_os.h ../../include/openssl/bio.h
 m_mdc2.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 m_mdc2.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
 m_mdc2.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
 m_mdc2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 m_mdc2.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-m_mdc2.o: ../../include/openssl/symhacks.h ../cryptlib.h m_mdc2.c
+m_mdc2.o: ../../include/openssl/symhacks.h ../cryptlib.h evp_locl.h m_mdc2.c
 m_null.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 m_null.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 m_null.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 m_null.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 m_null.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-m_null.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-m_null.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-m_null.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-m_null.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-m_null.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-m_null.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-m_null.o: ../../include/openssl/x509_vfy.h ../cryptlib.h m_null.c
+m_null.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+m_null.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+m_null.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+m_null.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+m_null.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+m_null.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+m_null.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+m_null.o: ../cryptlib.h m_null.c
 m_ripemd.o: ../../e_os.h ../../include/openssl/asn1.h
 m_ripemd.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 m_ripemd.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 m_ripemd.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 m_ripemd.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-m_ripemd.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-m_ripemd.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-m_ripemd.o: ../../include/openssl/opensslconf.h
+m_ripemd.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+m_ripemd.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+m_ripemd.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 m_ripemd.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 m_ripemd.o: ../../include/openssl/pkcs7.h ../../include/openssl/ripemd.h
 m_ripemd.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
@@ -493,60 +567,62 @@
 m_sha.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 m_sha.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 m_sha.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-m_sha.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-m_sha.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-m_sha.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-m_sha.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
-m_sha.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-m_sha.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-m_sha.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-m_sha.o: ../cryptlib.h m_sha.c
+m_sha.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+m_sha.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+m_sha.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+m_sha.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+m_sha.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+m_sha.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+m_sha.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+m_sha.o: ../../include/openssl/x509_vfy.h ../cryptlib.h evp_locl.h m_sha.c
 m_sha1.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 m_sha1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 m_sha1.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 m_sha1.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 m_sha1.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-m_sha1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-m_sha1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-m_sha1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-m_sha1.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
-m_sha1.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-m_sha1.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-m_sha1.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-m_sha1.o: ../cryptlib.h m_sha1.c
+m_sha1.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+m_sha1.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+m_sha1.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+m_sha1.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+m_sha1.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+m_sha1.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+m_sha1.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+m_sha1.o: ../../include/openssl/x509_vfy.h ../cryptlib.h m_sha1.c
 names.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 names.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 names.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 names.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 names.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-names.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-names.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-names.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-names.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-names.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-names.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-names.o: ../../include/openssl/x509_vfy.h ../cryptlib.h names.c
+names.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+names.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+names.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+names.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+names.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+names.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+names.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+names.o: ../cryptlib.h names.c
 p5_crpt.o: ../../e_os.h ../../include/openssl/asn1.h
 p5_crpt.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 p5_crpt.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 p5_crpt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 p5_crpt.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-p5_crpt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-p5_crpt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-p5_crpt.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-p5_crpt.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-p5_crpt.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-p5_crpt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-p5_crpt.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-p5_crpt.o: ../cryptlib.h p5_crpt.c
+p5_crpt.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+p5_crpt.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p5_crpt.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p5_crpt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p5_crpt.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+p5_crpt.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+p5_crpt.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+p5_crpt.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p5_crpt.c
 p5_crpt2.o: ../../e_os.h ../../include/openssl/asn1.h
 p5_crpt2.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 p5_crpt2.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 p5_crpt2.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 p5_crpt2.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-p5_crpt2.o: ../../include/openssl/evp.h ../../include/openssl/hmac.h
-p5_crpt2.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-p5_crpt2.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p5_crpt2.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+p5_crpt2.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+p5_crpt2.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p5_crpt2.o: ../../include/openssl/opensslconf.h
 p5_crpt2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 p5_crpt2.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 p5_crpt2.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -557,27 +633,29 @@
 p_dec.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 p_dec.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 p_dec.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-p_dec.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-p_dec.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-p_dec.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-p_dec.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
-p_dec.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-p_dec.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-p_dec.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-p_dec.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p_dec.c
+p_dec.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+p_dec.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p_dec.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+p_dec.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+p_dec.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+p_dec.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p_dec.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p_dec.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p_dec.o: ../cryptlib.h p_dec.c
 p_enc.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 p_enc.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 p_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 p_enc.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 p_enc.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-p_enc.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-p_enc.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-p_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-p_enc.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
-p_enc.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-p_enc.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-p_enc.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-p_enc.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p_enc.c
+p_enc.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+p_enc.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p_enc.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+p_enc.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+p_enc.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+p_enc.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p_enc.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p_enc.o: ../cryptlib.h p_enc.c
 p_lib.o: ../../e_os.h ../../include/openssl/asn1.h
 p_lib.o: ../../include/openssl/asn1_mac.h ../../include/openssl/bio.h
 p_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
@@ -585,60 +663,63 @@
 p_lib.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
 p_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 p_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-p_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-p_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-p_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-p_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-p_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-p_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-p_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-p_lib.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p_lib.c
+p_lib.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+p_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+p_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p_lib.o: ../cryptlib.h p_lib.c
 p_open.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 p_open.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 p_open.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 p_open.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 p_open.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-p_open.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-p_open.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-p_open.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-p_open.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
-p_open.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-p_open.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-p_open.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-p_open.o: ../cryptlib.h p_open.c
+p_open.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+p_open.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p_open.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+p_open.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+p_open.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+p_open.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+p_open.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+p_open.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p_open.c
 p_seal.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 p_seal.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 p_seal.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 p_seal.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 p_seal.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-p_seal.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-p_seal.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-p_seal.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-p_seal.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
-p_seal.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-p_seal.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-p_seal.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-p_seal.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p_seal.c
+p_seal.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+p_seal.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p_seal.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+p_seal.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+p_seal.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+p_seal.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p_seal.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p_seal.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p_seal.o: ../cryptlib.h p_seal.c
 p_sign.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 p_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 p_sign.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 p_sign.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 p_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-p_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-p_sign.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-p_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-p_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-p_sign.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-p_sign.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-p_sign.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p_sign.c
+p_sign.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+p_sign.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p_sign.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+p_sign.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+p_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p_sign.o: ../cryptlib.h p_sign.c
 p_verify.o: ../../e_os.h ../../include/openssl/asn1.h
 p_verify.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 p_verify.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 p_verify.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 p_verify.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-p_verify.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-p_verify.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-p_verify.o: ../../include/openssl/opensslconf.h
+p_verify.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+p_verify.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p_verify.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 p_verify.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 p_verify.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 p_verify.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
diff --git a/crypto/evp/bio_md.c b/crypto/evp/bio_md.c
index d648ac6..ed5c113 100644
--- a/crypto/evp/bio_md.c
+++ b/crypto/evp/bio_md.c
@@ -192,13 +192,8 @@
 			ret=0;
 		break;
 	case BIO_C_GET_MD_CTX:
-		if (b->init)
-			{
-			pctx=ptr;
-			*pctx=ctx;
-			}
-		else
-			ret=0;
+		pctx=ptr;
+		*pctx=ctx;
 		break;
 	case BIO_C_SET_MD_CTX:
 		if (b->init)
diff --git a/crypto/evp/dig_eng.c b/crypto/evp/dig_eng.c
new file mode 100644
index 0000000..64cdf93
--- /dev/null
+++ b/crypto/evp/dig_eng.c
@@ -0,0 +1,180 @@
+/* crypto/evp/digest.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 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).
+ *
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include "evp_locl.h"
+
+#ifndef OPENSSL_NO_ENGINE
+
+#ifdef OPENSSL_FIPS
+
+static int do_evp_md_engine_full(EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)
+	{
+	if (*ptype)
+		{
+		/* Ensure an ENGINE left lying around from last time is cleared
+		 * (the previous check attempted to avoid this if the same
+		 * ENGINE and EVP_MD could be used). */
+		if(ctx->engine)
+			ENGINE_finish(ctx->engine);
+		if(impl)
+			{
+			if (!ENGINE_init(impl))
+				{
+				EVPerr(EVP_F_DO_EVP_MD_ENGINE_FULL,EVP_R_INITIALIZATION_ERROR);
+				return 0;
+				}
+			}
+		else
+			/* Ask if an ENGINE is reserved for this job */
+			impl = ENGINE_get_digest_engine((*ptype)->type);
+		if(impl)
+			{
+			/* There's an ENGINE for this job ... (apparently) */
+			const EVP_MD *d = ENGINE_get_digest(impl, (*ptype)->type);
+			if(!d)
+				{
+				/* Same comment from evp_enc.c */
+				EVPerr(EVP_F_DO_EVP_MD_ENGINE_FULL,EVP_R_INITIALIZATION_ERROR);
+				return 0;
+				}
+			/* We'll use the ENGINE's private digest definition */
+			*ptype = d;
+			/* Store the ENGINE functional reference so we know
+			 * 'type' came from an ENGINE and we need to release
+			 * it when done. */
+			ctx->engine = impl;
+			}
+		else
+			ctx->engine = NULL;
+		}
+	else
+	if(!ctx->digest)
+		{
+		EVPerr(EVP_F_DO_EVP_MD_ENGINE_FULL,EVP_R_NO_DIGEST_SET);
+		return 0;
+		}
+	return 1;
+	}
+
+void int_EVP_MD_init_engine_callbacks(void)
+	{
+	int_EVP_MD_set_engine_callbacks(
+		ENGINE_init, ENGINE_finish, do_evp_md_engine_full);
+	}
+#endif
+#endif
diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c
index 762e6d3..3bc2d12 100644
--- a/crypto/evp/digest.c
+++ b/crypto/evp/digest.c
@@ -116,6 +116,7 @@
 #ifndef OPENSSL_NO_ENGINE
 #include <openssl/engine.h>
 #endif
+#include "evp_locl.h"
 
 void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
 	{
@@ -137,18 +138,77 @@
 	return EVP_DigestInit_ex(ctx, type, NULL);
 	}
 
-int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
+#ifdef OPENSSL_FIPS
+
+/* The purpose of these is to trap programs that attempt to use non FIPS
+ * algorithms in FIPS mode and ignore the errors.
+ */
+
+static int bad_init(EVP_MD_CTX *ctx)
+	{ FIPS_ERROR_IGNORED("Digest init"); return 0;}
+
+static int bad_update(EVP_MD_CTX *ctx,const void *data,size_t count)
+	{ FIPS_ERROR_IGNORED("Digest update"); return 0;}
+
+static int bad_final(EVP_MD_CTX *ctx,unsigned char *md)
+	{ FIPS_ERROR_IGNORED("Digest Final"); return 0;}
+
+static const EVP_MD bad_md =
 	{
-	EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
+	0,
+	0,
+	0,
+	0,
+	bad_init,
+	bad_update,
+	bad_final,
+	NULL,
+	NULL,
+	NULL,
+	0,
+	{0,0,0,0},
+	};
+
+#endif
+
 #ifndef OPENSSL_NO_ENGINE
-	/* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
-	 * so this context may already have an ENGINE! Try to avoid releasing
-	 * the previous handle, re-querying for an ENGINE, and having a
-	 * reinitialisation, when it may all be unecessary. */
-	if (ctx->engine && ctx->digest && (!type ||
-			(type && (type->type == ctx->digest->type))))
-		goto skip_to_init;
-	if (type)
+
+#ifdef OPENSSL_FIPS
+
+static int do_engine_null(ENGINE *impl) { return 0;}
+static int do_evp_md_engine_null(EVP_MD_CTX *ctx,
+				const EVP_MD **ptype, ENGINE *impl)
+	{ return 1; }
+
+static int (*do_engine_init)(ENGINE *impl)
+		= do_engine_null;
+
+static int (*do_engine_finish)(ENGINE *impl)
+		= do_engine_null;
+
+static int (*do_evp_md_engine)
+	(EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)
+		= do_evp_md_engine_null;
+
+void int_EVP_MD_set_engine_callbacks(
+	int (*eng_md_init)(ENGINE *impl),
+	int (*eng_md_fin)(ENGINE *impl),
+	int (*eng_md_evp)
+		(EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl))
+	{
+	do_engine_init = eng_md_init;
+	do_engine_finish = eng_md_fin;
+	do_evp_md_engine = eng_md_evp;
+	}
+
+#else
+
+#define do_engine_init	ENGINE_init
+#define do_engine_finish ENGINE_finish
+
+static int do_evp_md_engine(EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl)
+	{
+	if (*ptype)
 		{
 		/* Ensure an ENGINE left lying around from last time is cleared
 		 * (the previous check attempted to avoid this if the same
@@ -159,25 +219,25 @@
 			{
 			if (!ENGINE_init(impl))
 				{
-				EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR);
+				EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_INITIALIZATION_ERROR);
 				return 0;
 				}
 			}
 		else
 			/* Ask if an ENGINE is reserved for this job */
-			impl = ENGINE_get_digest_engine(type->type);
+			impl = ENGINE_get_digest_engine((*ptype)->type);
 		if(impl)
 			{
 			/* There's an ENGINE for this job ... (apparently) */
-			const EVP_MD *d = ENGINE_get_digest(impl, type->type);
+			const EVP_MD *d = ENGINE_get_digest(impl, (*ptype)->type);
 			if(!d)
 				{
 				/* Same comment from evp_enc.c */
-				EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR);
+				EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_INITIALIZATION_ERROR);
 				return 0;
 				}
 			/* We'll use the ENGINE's private digest definition */
-			type = d;
+			*ptype = d;
 			/* Store the ENGINE functional reference so we know
 			 * 'type' came from an ENGINE and we need to release
 			 * it when done. */
@@ -189,12 +249,52 @@
 	else
 	if(!ctx->digest)
 		{
-		EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_NO_DIGEST_SET);
+		EVPerr(EVP_F_DO_EVP_MD_ENGINE,EVP_R_NO_DIGEST_SET);
+		return 0;
+		}
+	return 1;
+	}
+
+#endif
+
+#endif
+
+int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
+	{
+	M_EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
+#ifdef OPENSSL_FIPS
+	if(FIPS_selftest_failed())
+		{
+		FIPSerr(FIPS_F_EVP_DIGESTINIT_EX,FIPS_R_FIPS_SELFTEST_FAILED);
+		ctx->digest = &bad_md;
 		return 0;
 		}
 #endif
+#ifndef OPENSSL_NO_ENGINE
+	/* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
+	 * so this context may already have an ENGINE! Try to avoid releasing
+	 * the previous handle, re-querying for an ENGINE, and having a
+	 * reinitialisation, when it may all be unecessary. */
+	if (ctx->engine && ctx->digest && (!type ||
+			(type && (type->type == ctx->digest->type))))
+		goto skip_to_init;
+	if (!do_evp_md_engine(ctx, &type, impl))
+		return 0;
+#endif
 	if (ctx->digest != type)
 		{
+#ifdef OPENSSL_FIPS
+		if (FIPS_mode())
+			{
+			if (!(type->flags & EVP_MD_FLAG_FIPS) 
+			 && !(ctx->flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW))
+				{
+				EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_DISABLED_FOR_FIPS);
+				ctx->digest = &bad_md;
+				return 0;
+				}
+			}
+#endif
 		if (ctx->digest && ctx->digest->ctx_size)
 			OPENSSL_free(ctx->md_data);
 		ctx->digest=type;
@@ -202,7 +302,7 @@
 			ctx->md_data=OPENSSL_malloc(type->ctx_size);
 		}
 #ifndef OPENSSL_NO_ENGINE
-skip_to_init:
+	skip_to_init:
 #endif
 	return ctx->digest->init(ctx);
 	}
@@ -210,6 +310,9 @@
 int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data,
 	     size_t count)
 	{
+#ifdef OPENSSL_FIPS
+	FIPS_selftest_check();
+#endif
 	return ctx->digest->update(ctx,data,count);
 	}
 
@@ -226,6 +329,9 @@
 int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
 	{
 	int ret;
+#ifdef OPENSSL_FIPS
+	FIPS_selftest_check();
+#endif
 
 	OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
 	ret=ctx->digest->final(ctx,md);
@@ -234,7 +340,7 @@
 	if (ctx->digest->cleanup)
 		{
 		ctx->digest->cleanup(ctx);
-		EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
+		M_EVP_MD_CTX_set_flags(ctx,EVP_MD_CTX_FLAG_CLEANED);
 		}
 	memset(ctx->md_data,0,ctx->digest->ctx_size);
 	return ret;
@@ -256,7 +362,7 @@
 		}
 #ifndef OPENSSL_NO_ENGINE
 	/* Make sure it's safe to copy a digest context using an ENGINE */
-	if (in->engine && !ENGINE_init(in->engine))
+	if (in->engine && !do_engine_init(in->engine))
 		{
 		EVPerr(EVP_F_EVP_MD_CTX_COPY_EX,ERR_R_ENGINE_LIB);
 		return 0;
@@ -266,7 +372,7 @@
 	if (out->digest == in->digest)
 		{
 		tmp_buf = out->md_data;
-	    	EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE);
+	    	M_EVP_MD_CTX_set_flags(out,EVP_MD_CTX_FLAG_REUSE);
 		}
 	else tmp_buf = NULL;
 	EVP_MD_CTX_cleanup(out);
@@ -292,7 +398,7 @@
 	int ret;
 
 	EVP_MD_CTX_init(&ctx);
-	EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT);
+	M_EVP_MD_CTX_set_flags(&ctx,EVP_MD_CTX_FLAG_ONESHOT);
 	ret=EVP_DigestInit_ex(&ctx, type, impl)
 	  && EVP_DigestUpdate(&ctx, data, count)
 	  && EVP_DigestFinal_ex(&ctx, md, size);
@@ -314,10 +420,10 @@
 	 * because sometimes only copies of the context are ever finalised.
 	 */
 	if (ctx->digest && ctx->digest->cleanup
-	    && !EVP_MD_CTX_test_flags(ctx,EVP_MD_CTX_FLAG_CLEANED))
+	    && !M_EVP_MD_CTX_test_flags(ctx,EVP_MD_CTX_FLAG_CLEANED))
 		ctx->digest->cleanup(ctx);
 	if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
-	    && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE))
+	    && !M_EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE))
 		{
 		OPENSSL_cleanse(ctx->md_data,ctx->digest->ctx_size);
 		OPENSSL_free(ctx->md_data);
@@ -326,7 +432,7 @@
 	if(ctx->engine)
 		/* The EVP_MD we used belongs to an ENGINE, release the
 		 * functional reference we held for this reason. */
-		ENGINE_finish(ctx->engine);
+		do_engine_finish(ctx->engine);
 #endif
 	memset(ctx,'\0',sizeof *ctx);
 
diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c
index bd6c0a3..c9a5ee8 100644
--- a/crypto/evp/e_aes.c
+++ b/crypto/evp/e_aes.c
@@ -69,32 +69,29 @@
 
 IMPLEMENT_BLOCK_CIPHER(aes_128, ks, AES, EVP_AES_KEY,
 		       NID_aes_128, 16, 16, 16, 128,
-		       0, aes_init_key, NULL, 
-		       EVP_CIPHER_set_asn1_iv,
-		       EVP_CIPHER_get_asn1_iv,
-		       NULL)
+		       EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
+		       aes_init_key,
+		       NULL, NULL, NULL, NULL)
 IMPLEMENT_BLOCK_CIPHER(aes_192, ks, AES, EVP_AES_KEY,
 		       NID_aes_192, 16, 24, 16, 128,
-		       0, aes_init_key, NULL, 
-		       EVP_CIPHER_set_asn1_iv,
-		       EVP_CIPHER_get_asn1_iv,
-		       NULL)
+		       EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
+		       aes_init_key,
+		       NULL, NULL, NULL, NULL)
 IMPLEMENT_BLOCK_CIPHER(aes_256, ks, AES, EVP_AES_KEY,
 		       NID_aes_256, 16, 32, 16, 128,
-		       0, aes_init_key, NULL, 
-		       EVP_CIPHER_set_asn1_iv,
-		       EVP_CIPHER_get_asn1_iv,
-		       NULL)
+		       EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
+		       aes_init_key,
+		       NULL, NULL, NULL, NULL)
 
-#define IMPLEMENT_AES_CFBR(ksize,cbits)	IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16)
+#define IMPLEMENT_AES_CFBR(ksize,cbits,flags)	IMPLEMENT_CFBR(aes,AES,EVP_AES_KEY,ks,ksize,cbits,16,flags)
 
-IMPLEMENT_AES_CFBR(128,1)
-IMPLEMENT_AES_CFBR(192,1)
-IMPLEMENT_AES_CFBR(256,1)
+IMPLEMENT_AES_CFBR(128,1,EVP_CIPH_FLAG_FIPS)
+IMPLEMENT_AES_CFBR(192,1,EVP_CIPH_FLAG_FIPS)
+IMPLEMENT_AES_CFBR(256,1,EVP_CIPH_FLAG_FIPS)
 
-IMPLEMENT_AES_CFBR(128,8)
-IMPLEMENT_AES_CFBR(192,8)
-IMPLEMENT_AES_CFBR(256,8)
+IMPLEMENT_AES_CFBR(128,8,EVP_CIPH_FLAG_FIPS)
+IMPLEMENT_AES_CFBR(192,8,EVP_CIPH_FLAG_FIPS)
+IMPLEMENT_AES_CFBR(256,8,EVP_CIPH_FLAG_FIPS)
 
 static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
 		   const unsigned char *iv, int enc)
diff --git a/crypto/evp/e_camellia.c b/crypto/evp/e_camellia.c
index a7b40d1..365d397 100644
--- a/crypto/evp/e_camellia.c
+++ b/crypto/evp/e_camellia.c
@@ -93,7 +93,7 @@
 	EVP_CIPHER_get_asn1_iv,
 	NULL)
 
-#define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits)	IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16)
+#define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits)	IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16,0)
 
 IMPLEMENT_CAMELLIA_CFBR(128,1)
 IMPLEMENT_CAMELLIA_CFBR(192,1)
diff --git a/crypto/evp/e_des.c b/crypto/evp/e_des.c
index 8563236..04376df 100644
--- a/crypto/evp/e_des.c
+++ b/crypto/evp/e_des.c
@@ -129,18 +129,21 @@
     }
 
 BLOCK_CIPHER_defs(des, DES_key_schedule, NID_des, 8, 8, 8, 64,
-			EVP_CIPH_RAND_KEY, des_init_key, NULL,
+			EVP_CIPH_RAND_KEY,
+			des_init_key, NULL,
 			EVP_CIPHER_set_asn1_iv,
 			EVP_CIPHER_get_asn1_iv,
 			des_ctrl)
 
 BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,1,
-		     EVP_CIPH_RAND_KEY, des_init_key,NULL,
+		     EVP_CIPH_RAND_KEY,
+		     des_init_key, NULL,
 		     EVP_CIPHER_set_asn1_iv,
 		     EVP_CIPHER_get_asn1_iv,des_ctrl)
 
 BLOCK_CIPHER_def_cfb(des,DES_key_schedule,NID_des,8,8,8,
-		     EVP_CIPH_RAND_KEY,des_init_key,NULL,
+		     EVP_CIPH_RAND_KEY,
+		     des_init_key,NULL,
 		     EVP_CIPHER_set_asn1_iv,
 		     EVP_CIPHER_get_asn1_iv,des_ctrl)
 
diff --git a/crypto/evp/e_des3.c b/crypto/evp/e_des3.c
index ac148ef..f910af1 100644
--- a/crypto/evp/e_des3.c
+++ b/crypto/evp/e_des3.c
@@ -111,8 +111,7 @@
 #ifdef KSSL_DEBUG
 	{
         int i;
-        char *cp;
-	printf("des_ede_cbc_cipher(ctx=%lx, buflen=%d)\n", ctx, ctx->buf_len);
+	printf("des_ede_cbc_cipher(ctx=%lx, buflen=%d)\n", (unsigned long)ctx, ctx->buf_len);
 	printf("\t iv= ");
         for(i=0;i<8;i++)
                 printf("%02X",ctx->iv[i]);
@@ -164,9 +163,9 @@
     }
 
 BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64,
-			EVP_CIPH_RAND_KEY, des_ede_init_key, NULL, 
-			EVP_CIPHER_set_asn1_iv,
-			EVP_CIPHER_get_asn1_iv,
+		EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
+			des_ede_init_key,
+			NULL, NULL, NULL,
 			des3_ctrl)
 
 #define des_ede3_cfb64_cipher des_ede_cfb64_cipher
@@ -175,21 +174,21 @@
 #define des_ede3_ecb_cipher des_ede_ecb_cipher
 
 BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64,
-			EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, 
-			EVP_CIPHER_set_asn1_iv,
-			EVP_CIPHER_get_asn1_iv,
+		EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
+			des_ede3_init_key,
+			NULL, NULL, NULL,
 			des3_ctrl)
 
 BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,1,
-		     EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL,
-		     EVP_CIPHER_set_asn1_iv,
-		     EVP_CIPHER_get_asn1_iv,
+		EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
+		     des_ede3_init_key,
+		     NULL, NULL, NULL,
 		     des3_ctrl)
 
 BLOCK_CIPHER_def_cfb(des_ede3,DES_EDE_KEY,NID_des_ede3,24,8,8,
-		     EVP_CIPH_RAND_KEY, des_ede3_init_key,NULL,
-		     EVP_CIPHER_set_asn1_iv,
-		     EVP_CIPHER_get_asn1_iv,
+		EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
+		     des_ede3_init_key,
+		     NULL, NULL, NULL,
 		     des3_ctrl)
 
 static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
@@ -216,7 +215,7 @@
 #ifdef KSSL_DEBUG
 	{
         int i;
-        printf("des_ede3_init_key(ctx=%lx)\n", ctx);
+        printf("des_ede3_init_key(ctx=%lx)\n", (unsigned long)ctx);
 	printf("\tKEY= ");
         for(i=0;i<24;i++) printf("%02X",key[i]); printf("\n");
 	printf("\t IV= ");
diff --git a/crypto/evp/e_null.c b/crypto/evp/e_null.c
index 5205259..0872d73 100644
--- a/crypto/evp/e_null.c
+++ b/crypto/evp/e_null.c
@@ -69,7 +69,7 @@
 	{
 	NID_undef,
 	1,0,0,
-	0,
+	EVP_CIPH_FLAG_FIPS,
 	null_init_key,
 	null_cipher,
 	NULL,
diff --git a/crypto/evp/e_rc4.c b/crypto/evp/e_rc4.c
index 67af850..55baad7 100644
--- a/crypto/evp/e_rc4.c
+++ b/crypto/evp/e_rc4.c
@@ -64,6 +64,7 @@
 #include <openssl/evp.h>
 #include <openssl/objects.h>
 #include <openssl/rc4.h>
+#include "evp_locl.h"
 
 /* FIXME: surely this is available elsewhere? */
 #define EVP_RC4_KEY_SIZE		16
diff --git a/crypto/evp/enc_min.c b/crypto/evp/enc_min.c
new file mode 100644
index 0000000..7fba38e
--- /dev/null
+++ b/crypto/evp/enc_min.c
@@ -0,0 +1,390 @@
+/* crypto/evp/enc_min.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+#include "evp_locl.h"
+
+void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
+	{
+#ifdef OPENSSL_FIPS
+	FIPS_selftest_check();
+#endif
+	memset(ctx,0,sizeof(EVP_CIPHER_CTX));
+	/* ctx->cipher=NULL; */
+	}
+
+#ifdef OPENSSL_FIPS
+
+/* The purpose of these is to trap programs that attempt to use non FIPS
+ * algorithms in FIPS mode and ignore the errors.
+ */
+
+static int bad_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+		    const unsigned char *iv, int enc)
+	{ FIPS_ERROR_IGNORED("Cipher init"); return 0;}
+
+static int bad_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+			 const unsigned char *in, unsigned int inl)
+	{ FIPS_ERROR_IGNORED("Cipher update"); return 0;}
+
+/* NB: no cleanup because it is allowed after failed init */
+
+static int bad_set_asn1(EVP_CIPHER_CTX *ctx, ASN1_TYPE *typ)
+	{ FIPS_ERROR_IGNORED("Cipher set_asn1"); return 0;}
+static int bad_get_asn1(EVP_CIPHER_CTX *ctx, ASN1_TYPE *typ)
+	{ FIPS_ERROR_IGNORED("Cipher get_asn1"); return 0;}
+static int bad_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+	{ FIPS_ERROR_IGNORED("Cipher ctrl"); return 0;}
+
+static const EVP_CIPHER bad_cipher =
+	{
+	0,
+	0,
+	0,
+	0,
+	0,
+	bad_init,
+	bad_do_cipher,
+	NULL,
+	0,
+	bad_set_asn1,
+	bad_get_asn1,
+	bad_ctrl,
+	NULL
+	};
+
+#endif
+
+#ifndef OPENSSL_NO_ENGINE
+
+#ifdef OPENSSL_FIPS
+
+static int do_engine_null(ENGINE *impl) { return 0;}
+static int do_evp_enc_engine_null(EVP_CIPHER_CTX *ctx,
+				const EVP_CIPHER **pciph, ENGINE *impl)
+	{ return 1; }
+
+static int (*do_engine_finish)(ENGINE *impl)
+		= do_engine_null;
+
+static int (*do_evp_enc_engine)
+	(EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pciph, ENGINE *impl)
+		= do_evp_enc_engine_null;
+
+void int_EVP_CIPHER_set_engine_callbacks(
+	int (*eng_ciph_fin)(ENGINE *impl),
+	int (*eng_ciph_evp)
+		(EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pciph, ENGINE *impl))
+	{
+	do_engine_finish = eng_ciph_fin;
+	do_evp_enc_engine = eng_ciph_evp;
+	}
+
+#else
+
+#define do_engine_finish ENGINE_finish
+
+static int do_evp_enc_engine(EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pcipher, ENGINE *impl)
+	{
+	if(impl)
+		{
+		if (!ENGINE_init(impl))
+			{
+			EVPerr(EVP_F_DO_EVP_ENC_ENGINE, EVP_R_INITIALIZATION_ERROR);
+			return 0;
+			}
+		}
+	else
+		/* Ask if an ENGINE is reserved for this job */
+		impl = ENGINE_get_cipher_engine((*pcipher)->nid);
+	if(impl)
+		{
+		/* There's an ENGINE for this job ... (apparently) */
+		const EVP_CIPHER *c = ENGINE_get_cipher(impl, (*pcipher)->nid);
+		if(!c)
+			{
+			/* One positive side-effect of US's export
+			 * control history, is that we should at least
+			 * be able to avoid using US mispellings of
+			 * "initialisation"? */
+			EVPerr(EVP_F_DO_EVP_ENC_ENGINE, EVP_R_INITIALIZATION_ERROR);
+			return 0;
+			}
+		/* We'll use the ENGINE's private cipher definition */
+		*pcipher = c;
+		/* Store the ENGINE functional reference so we know
+		 * 'cipher' came from an ENGINE and we need to release
+		 * it when done. */
+		ctx->engine = impl;
+		}
+	else
+		ctx->engine = NULL;
+	return 1;
+	}
+
+#endif
+
+#endif
+
+int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
+	     const unsigned char *key, const unsigned char *iv, int enc)
+	{
+	if (enc == -1)
+		enc = ctx->encrypt;
+	else
+		{
+		if (enc)
+			enc = 1;
+		ctx->encrypt = enc;
+		}
+#ifdef OPENSSL_FIPS
+	if(FIPS_selftest_failed())
+		{
+		FIPSerr(FIPS_F_EVP_CIPHERINIT_EX,FIPS_R_FIPS_SELFTEST_FAILED);
+		ctx->cipher = &bad_cipher;
+		return 0;
+		}
+#endif
+#ifndef OPENSSL_NO_ENGINE
+	/* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
+	 * so this context may already have an ENGINE! Try to avoid releasing
+	 * the previous handle, re-querying for an ENGINE, and having a
+	 * reinitialisation, when it may all be unecessary. */
+	if (ctx->engine && ctx->cipher && (!cipher ||
+			(cipher && (cipher->nid == ctx->cipher->nid))))
+		goto skip_to_init;
+#endif
+	if (cipher)
+		{
+		/* Ensure a context left lying around from last time is cleared
+		 * (the previous check attempted to avoid this if the same
+		 * ENGINE and EVP_CIPHER could be used). */
+		EVP_CIPHER_CTX_cleanup(ctx);
+
+		/* Restore encrypt field: it is zeroed by cleanup */
+		ctx->encrypt = enc;
+#ifndef OPENSSL_NO_ENGINE
+		if (!do_evp_enc_engine(ctx, &cipher, impl))
+			return 0;
+#endif
+
+		ctx->cipher=cipher;
+		if (ctx->cipher->ctx_size)
+			{
+			ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
+			if (!ctx->cipher_data)
+				{
+				EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
+				return 0;
+				}
+			}
+		else
+			{
+			ctx->cipher_data = NULL;
+			}
+		ctx->key_len = cipher->key_len;
+		ctx->flags = 0;
+		if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)
+			{
+			if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))
+				{
+				EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
+				return 0;
+				}
+			}
+		}
+	else if(!ctx->cipher)
+		{
+		EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET);
+		return 0;
+		}
+#ifndef OPENSSL_NO_ENGINE
+skip_to_init:
+#endif
+	/* we assume block size is a power of 2 in *cryptUpdate */
+	OPENSSL_assert(ctx->cipher->block_size == 1
+	    || ctx->cipher->block_size == 8
+	    || ctx->cipher->block_size == 16);
+
+	if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
+		switch(EVP_CIPHER_CTX_mode(ctx)) {
+
+			case EVP_CIPH_STREAM_CIPHER:
+			case EVP_CIPH_ECB_MODE:
+			break;
+
+			case EVP_CIPH_CFB_MODE:
+			case EVP_CIPH_OFB_MODE:
+
+			ctx->num = 0;
+
+			case EVP_CIPH_CBC_MODE:
+
+			OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <=
+					(int)sizeof(ctx->iv));
+			if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
+			memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
+			break;
+
+			default:
+			return 0;
+			break;
+		}
+	}
+
+#ifdef OPENSSL_FIPS
+	/* After 'key' is set no further parameters changes are permissible.
+	 * So only check for non FIPS enabling at this point.
+	 */
+	if (key && FIPS_mode())
+		{
+		if (!(ctx->cipher->flags & EVP_CIPH_FLAG_FIPS)
+			& !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW))
+			{
+			EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_DISABLED_FOR_FIPS);
+#if 0
+			ERR_add_error_data(2, "cipher=",
+						EVP_CIPHER_name(ctx->cipher));
+#endif
+			ctx->cipher = &bad_cipher;
+			return 0;
+			}
+		}
+#endif
+
+	if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
+		if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;
+	}
+	ctx->buf_len=0;
+	ctx->final_used=0;
+	ctx->block_mask=ctx->cipher->block_size-1;
+	return 1;
+	}
+
+int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
+	{
+	if (c->cipher != NULL)
+		{
+		if(c->cipher->cleanup && !c->cipher->cleanup(c))
+			return 0;
+		/* Cleanse cipher context data */
+		if (c->cipher_data)
+			OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
+		}
+	if (c->cipher_data)
+		OPENSSL_free(c->cipher_data);
+#ifndef OPENSSL_NO_ENGINE
+	if (c->engine)
+		/* The EVP_CIPHER we used belongs to an ENGINE, release the
+		 * functional reference we held for this reason. */
+		do_engine_finish(c->engine);
+#endif
+	memset(c,0,sizeof(EVP_CIPHER_CTX));
+	return 1;
+	}
+
+int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl)
+	{
+#ifdef OPENSSL_FIPS
+	FIPS_selftest_check();
+#endif
+	return ctx->cipher->do_cipher(ctx,out,in,inl);
+	}
+
+int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
+{
+	int ret;
+	if(!ctx->cipher) {
+		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
+		return 0;
+	}
+
+	if(!ctx->cipher->ctrl) {
+		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
+		return 0;
+	}
+
+	ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
+	if(ret == -1) {
+		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
+		return 0;
+	}
+	return ret;
+}
+
+unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
+	{
+	return ctx->cipher->flags;
+	}
+
+int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
+	{
+	return ctx->cipher->iv_len;
+	}
+
+int EVP_CIPHER_nid(const EVP_CIPHER *cipher)
+	{
+	return cipher->nid;
+	}
diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h
index bdd3b7e..79c0971 100644
--- a/crypto/evp/evp.h
+++ b/crypto/evp/evp.h
@@ -75,6 +75,10 @@
 #include <openssl/bio.h>
 #endif
 
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 /*
 #define EVP_RC2_KEY_SIZE		16
 #define EVP_RC4_KEY_SIZE		16
@@ -250,9 +254,19 @@
 			    unsigned int m_length,const unsigned char *sigbuf,
 			    unsigned int siglen, void *key);
 
+typedef struct
+	{
+	EVP_MD_CTX *mctx;
+	void *key;
+	} EVP_MD_SVCTX;
+
 #define EVP_MD_FLAG_ONESHOT	0x0001 /* digest can only handle a single
 					* block */
 
+#define EVP_MD_FLAG_FIPS	0x0400 /* Note if suitable for use in FIPS mode */
+
+#define EVP_MD_FLAG_SVCTX	0x0800 /* pass EVP_MD_SVCTX to sign/verify */
+
 #define EVP_PKEY_NULL_method	NULL,NULL,{0,0,0,0}
 
 #ifndef OPENSSL_NO_DSA
@@ -303,6 +317,17 @@
 						* cleaned */
 #define EVP_MD_CTX_FLAG_REUSE		0x0004 /* Don't free up ctx->md_data
 						* in EVP_MD_CTX_cleanup */
+#define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW	0x0008	/* Allow use of non FIPS digest
+						 * in FIPS mode */
+
+#define EVP_MD_CTX_FLAG_PAD_MASK	0xF0	/* RSA mode to use */
+#define EVP_MD_CTX_FLAG_PAD_PKCS1	0x00	/* PKCS#1 v1.5 mode */
+#define EVP_MD_CTX_FLAG_PAD_X931	0x10	/* X9.31 mode */
+#define EVP_MD_CTX_FLAG_PAD_PSS		0x20	/* PSS mode */
+#define M_EVP_MD_CTX_FLAG_PSS_SALT(ctx) \
+		((ctx->flags>>16) &0xFFFF) /* seed length */
+#define EVP_MD_CTX_FLAG_PSS_MDLEN	0xFFFF	/* salt len same as digest */
+#define EVP_MD_CTX_FLAG_PSS_MREC	0xFFFE	/* salt max or auto recovered */
 
 struct evp_cipher_st
 	{
@@ -347,6 +372,14 @@
 #define 	EVP_CIPH_NO_PADDING		0x100
 /* cipher handles random key generation */
 #define 	EVP_CIPH_RAND_KEY		0x200
+/* Note if suitable for use in FIPS mode */
+#define		EVP_CIPH_FLAG_FIPS		0x400
+/* Allow non FIPS cipher in FIPS mode */
+#define		EVP_CIPH_FLAG_NON_FIPS_ALLOW	0x800
+/* Allow use default ASN1 get/set iv */
+#define		EVP_CIPH_FLAG_DEFAULT_ASN1	0x1000
+/* Buffer length in bits not bytes: CFB1 mode only */
+#define		EVP_CIPH_FLAG_LENGTH_BITS	0x2000
 
 /* ctrl() values */
 
@@ -429,6 +462,18 @@
 #define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a))
 #define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a))
 
+/* Macros to reduce FIPS dependencies: do NOT use in applications */
+#define M_EVP_MD_size(e)		((e)->md_size)
+#define M_EVP_MD_block_size(e)		((e)->block_size)
+#define M_EVP_MD_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs))
+#define M_EVP_MD_CTX_clear_flags(ctx,flgs) ((ctx)->flags&=~(flgs))
+#define M_EVP_MD_CTX_test_flags(ctx,flgs) ((ctx)->flags&(flgs))
+#define M_EVP_MD_type(e)			((e)->type)
+#define M_EVP_MD_CTX_type(e)		M_EVP_MD_type(M_EVP_MD_CTX_md(e))
+#define M_EVP_MD_CTX_md(e)			((e)->digest)
+
+#define M_EVP_CIPHER_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs))
+
 int EVP_MD_type(const EVP_MD *md);
 #define EVP_MD_nid(e)			EVP_MD_type(e)
 #define EVP_MD_name(e)			OBJ_nid2sn(EVP_MD_nid(e))
@@ -524,6 +569,10 @@
 		const unsigned char *salt, const unsigned char *data,
 		int datal, int count, unsigned char *key,unsigned char *iv);
 
+void	EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags);
+void	EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags);
+int 	EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx,int flags);
+
 int	EVP_EncryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher,
 		const unsigned char *key, const unsigned char *iv);
 int	EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
@@ -879,6 +928,24 @@
 		    EVP_PBE_KEYGEN *keygen);
 void EVP_PBE_cleanup(void);
 
+#ifdef OPENSSL_FIPS
+#ifndef OPENSSL_NO_ENGINE
+void int_EVP_MD_set_engine_callbacks(
+	int (*eng_md_init)(ENGINE *impl),
+	int (*eng_md_fin)(ENGINE *impl),
+	int (*eng_md_evp)
+		(EVP_MD_CTX *ctx, const EVP_MD **ptype, ENGINE *impl));
+void int_EVP_MD_init_engine_callbacks(void);
+void int_EVP_CIPHER_set_engine_callbacks(
+	int (*eng_ciph_fin)(ENGINE *impl),
+	int (*eng_ciph_evp)
+		(EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pciph, ENGINE *impl));
+void int_EVP_CIPHER_init_engine_callbacks(void);
+#endif
+#endif
+
+void EVP_add_alg_module(void);
+
 /* BEGIN ERROR CODES */
 /* The following lines are auto generated by the script mkerr.pl. Any changes
  * made after this point may be overwritten when the script is next run.
@@ -889,16 +956,23 @@
 
 /* Function codes. */
 #define EVP_F_AES_INIT_KEY				 133
+#define EVP_F_ALG_MODULE_INIT				 138
 #define EVP_F_CAMELLIA_INIT_KEY				 159
 #define EVP_F_D2I_PKEY					 100
+#define EVP_F_DO_EVP_ENC_ENGINE				 140
+#define EVP_F_DO_EVP_ENC_ENGINE_FULL			 141
+#define EVP_F_DO_EVP_MD_ENGINE				 139
+#define EVP_F_DO_EVP_MD_ENGINE_FULL			 142
 #define EVP_F_DSAPKEY2PKCS8				 134
 #define EVP_F_DSA_PKEY2PKCS8				 135
 #define EVP_F_ECDSA_PKEY2PKCS8				 129
 #define EVP_F_ECKEY_PKEY2PKCS8				 132
+#define EVP_F_EVP_CIPHERINIT				 137
 #define EVP_F_EVP_CIPHERINIT_EX				 123
 #define EVP_F_EVP_CIPHER_CTX_CTRL			 124
 #define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH		 122
 #define EVP_F_EVP_DECRYPTFINAL_EX			 101
+#define EVP_F_EVP_DIGESTINIT				 136
 #define EVP_F_EVP_DIGESTINIT_EX				 128
 #define EVP_F_EVP_ENCRYPTFINAL_EX			 127
 #define EVP_F_EVP_MD_CTX_COPY_EX			 110
@@ -940,15 +1014,20 @@
 #define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH		 138
 #define EVP_R_DECODE_ERROR				 114
 #define EVP_R_DIFFERENT_KEY_TYPES			 101
+#define EVP_R_DISABLED_FOR_FIPS				 144
 #define EVP_R_ENCODE_ERROR				 115
+#define EVP_R_ERROR_LOADING_SECTION			 145
+#define EVP_R_ERROR_SETTING_FIPS_MODE			 146
 #define EVP_R_EVP_PBE_CIPHERINIT_ERROR			 119
 #define EVP_R_EXPECTING_AN_RSA_KEY			 127
 #define EVP_R_EXPECTING_A_DH_KEY			 128
 #define EVP_R_EXPECTING_A_DSA_KEY			 129
 #define EVP_R_EXPECTING_A_ECDSA_KEY			 141
 #define EVP_R_EXPECTING_A_EC_KEY			 142
+#define EVP_R_FIPS_MODE_NOT_SUPPORTED			 147
 #define EVP_R_INITIALIZATION_ERROR			 134
 #define EVP_R_INPUT_NOT_INITIALIZED			 111
+#define EVP_R_INVALID_FIPS_MODE				 148
 #define EVP_R_INVALID_KEY_LENGTH			 130
 #define EVP_R_IV_TOO_LARGE				 102
 #define EVP_R_KEYGEN_FAILURE				 120
@@ -960,6 +1039,7 @@
 #define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED		 105
 #define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE			 117
 #define EVP_R_PUBLIC_KEY_NOT_RSA			 106
+#define EVP_R_UNKNOWN_OPTION				 149
 #define EVP_R_UNKNOWN_PBE_ALGORITHM			 121
 #define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS		 135
 #define EVP_R_UNSUPPORTED_CIPHER			 107
diff --git a/crypto/evp/evp_acnf.c b/crypto/evp/evp_acnf.c
index ff3e311..643a186 100644
--- a/crypto/evp/evp_acnf.c
+++ b/crypto/evp/evp_acnf.c
@@ -1,5 +1,5 @@
 /* evp_acnf.c */
-/* Written by Stephen Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
  * project 2001.
  */
 /* ====================================================================
diff --git a/crypto/evp/evp_cnf.c b/crypto/evp/evp_cnf.c
new file mode 100644
index 0000000..2e4db30
--- /dev/null
+++ b/crypto/evp/evp_cnf.c
@@ -0,0 +1,125 @@
+/* evp_cnf.c */
+/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
+ * project 2007.
+ */
+/* ====================================================================
+ * Copyright (c) 2007 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.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/conf.h>
+#include <openssl/dso.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
+
+/* Algorithm configuration module. */
+
+static int alg_module_init(CONF_IMODULE *md, const CONF *cnf)
+	{
+	int i;
+	const char *oid_section;
+	STACK_OF(CONF_VALUE) *sktmp;
+	CONF_VALUE *oval;
+	oid_section = CONF_imodule_get_value(md);
+	if(!(sktmp = NCONF_get_section(cnf, oid_section)))
+		{
+		EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION);
+		return 0;
+		}
+	for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++)
+		{
+		oval = sk_CONF_VALUE_value(sktmp, i);
+		if (!strcmp(oval->name, "fips_mode"))
+			{
+			int m;
+			if (!X509V3_get_value_bool(oval, &m))
+				{
+				EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_INVALID_FIPS_MODE);
+				return 0;
+				}
+			if (m > 0)
+				{
+#ifdef OPENSSL_FIPS
+				if (!FIPS_mode() && !FIPS_mode_set(1))
+					{
+					EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_SETTING_FIPS_MODE);
+					return 0;
+					}
+#else
+				EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_FIPS_MODE_NOT_SUPPORTED);
+				return 0;
+#endif
+				}
+			}
+		else
+			{
+			EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION);
+			ERR_add_error_data(4, "name=", oval->name,
+						", value=", oval->value);
+			}
+				
+		}
+	return 1;
+	}
+
+void EVP_add_alg_module(void)
+	{
+	CONF_module_add("alg_section", alg_module_init, 0);
+	}
diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c
index a190499..30e0ca4 100644
--- a/crypto/evp/evp_enc.c
+++ b/crypto/evp/evp_enc.c
@@ -66,13 +66,15 @@
 #endif
 #include "evp_locl.h"
 
-const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT;
+#ifdef OPENSSL_FIPS
+	#define M_do_cipher(ctx, out, in, inl) \
+		EVP_Cipher(ctx,out,in,inl)
+#else
+	#define M_do_cipher(ctx, out, in, inl) \
+		ctx->cipher->do_cipher(ctx,out,in,inl)
+#endif
 
-void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx)
-	{
-	memset(ctx,0,sizeof(EVP_CIPHER_CTX));
-	/* ctx->cipher=NULL; */
-	}
+const char EVP_version[]="EVP" OPENSSL_VERSION_PTEXT;
 
 EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
 	{
@@ -90,144 +92,6 @@
 	return EVP_CipherInit_ex(ctx,cipher,NULL,key,iv,enc);
 	}
 
-int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ENGINE *impl,
-	     const unsigned char *key, const unsigned char *iv, int enc)
-	{
-	if (enc == -1)
-		enc = ctx->encrypt;
-	else
-		{
-		if (enc)
-			enc = 1;
-		ctx->encrypt = enc;
-		}
-#ifndef OPENSSL_NO_ENGINE
-	/* Whether it's nice or not, "Inits" can be used on "Final"'d contexts
-	 * so this context may already have an ENGINE! Try to avoid releasing
-	 * the previous handle, re-querying for an ENGINE, and having a
-	 * reinitialisation, when it may all be unecessary. */
-	if (ctx->engine && ctx->cipher && (!cipher ||
-			(cipher && (cipher->nid == ctx->cipher->nid))))
-		goto skip_to_init;
-#endif
-	if (cipher)
-		{
-		/* Ensure a context left lying around from last time is cleared
-		 * (the previous check attempted to avoid this if the same
-		 * ENGINE and EVP_CIPHER could be used). */
-		EVP_CIPHER_CTX_cleanup(ctx);
-
-		/* Restore encrypt field: it is zeroed by cleanup */
-		ctx->encrypt = enc;
-#ifndef OPENSSL_NO_ENGINE
-		if(impl)
-			{
-			if (!ENGINE_init(impl))
-				{
-				EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
-				return 0;
-				}
-			}
-		else
-			/* Ask if an ENGINE is reserved for this job */
-			impl = ENGINE_get_cipher_engine(cipher->nid);
-		if(impl)
-			{
-			/* There's an ENGINE for this job ... (apparently) */
-			const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid);
-			if(!c)
-				{
-				/* One positive side-effect of US's export
-				 * control history, is that we should at least
-				 * be able to avoid using US mispellings of
-				 * "initialisation"? */
-				EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
-				return 0;
-				}
-			/* We'll use the ENGINE's private cipher definition */
-			cipher = c;
-			/* Store the ENGINE functional reference so we know
-			 * 'cipher' came from an ENGINE and we need to release
-			 * it when done. */
-			ctx->engine = impl;
-			}
-		else
-			ctx->engine = NULL;
-#endif
-
-		ctx->cipher=cipher;
-		if (ctx->cipher->ctx_size)
-			{
-			ctx->cipher_data=OPENSSL_malloc(ctx->cipher->ctx_size);
-			if (!ctx->cipher_data)
-				{
-				EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
-				return 0;
-				}
-			}
-		else
-			{
-			ctx->cipher_data = NULL;
-			}
-		ctx->key_len = cipher->key_len;
-		ctx->flags = 0;
-		if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT)
-			{
-			if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL))
-				{
-				EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
-				return 0;
-				}
-			}
-		}
-	else if(!ctx->cipher)
-		{
-		EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET);
-		return 0;
-		}
-#ifndef OPENSSL_NO_ENGINE
-skip_to_init:
-#endif
-	/* we assume block size is a power of 2 in *cryptUpdate */
-	OPENSSL_assert(ctx->cipher->block_size == 1
-	    || ctx->cipher->block_size == 8
-	    || ctx->cipher->block_size == 16);
-
-	if(!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) {
-		switch(EVP_CIPHER_CTX_mode(ctx)) {
-
-			case EVP_CIPH_STREAM_CIPHER:
-			case EVP_CIPH_ECB_MODE:
-			break;
-
-			case EVP_CIPH_CFB_MODE:
-			case EVP_CIPH_OFB_MODE:
-
-			ctx->num = 0;
-
-			case EVP_CIPH_CBC_MODE:
-
-			OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <=
-					(int)sizeof(ctx->iv));
-			if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
-			memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
-			break;
-
-			default:
-			return 0;
-			break;
-		}
-	}
-
-	if(key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) {
-		if(!ctx->cipher->init(ctx,key,iv,enc)) return 0;
-	}
-	ctx->buf_len=0;
-	ctx->final_used=0;
-	ctx->block_mask=ctx->cipher->block_size-1;
-	return 1;
-	}
-
 int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
 	     const unsigned char *in, int inl)
 	{
@@ -279,10 +143,15 @@
 	{
 	int i,j,bl;
 
-	OPENSSL_assert(inl > 0);
+	if (inl <= 0)
+		{
+		*outl = 0;
+		return inl == 0;
+		}
+
 	if(ctx->buf_len == 0 && (inl&(ctx->block_mask)) == 0)
 		{
-		if(ctx->cipher->do_cipher(ctx,out,in,inl))
+		if(M_do_cipher(ctx,out,in,inl))
 			{
 			*outl=inl;
 			return 1;
@@ -309,7 +178,7 @@
 			{
 			j=bl-i;
 			memcpy(&(ctx->buf[i]),in,j);
-			if(!ctx->cipher->do_cipher(ctx,out,ctx->buf,bl)) return 0;
+			if(!M_do_cipher(ctx,out,ctx->buf,bl)) return 0;
 			inl-=j;
 			in+=j;
 			out+=bl;
@@ -322,7 +191,7 @@
 	inl-=i;
 	if (inl > 0)
 		{
-		if(!ctx->cipher->do_cipher(ctx,out,in,inl)) return 0;
+		if(!M_do_cipher(ctx,out,in,inl)) return 0;
 		*outl+=inl;
 		}
 
@@ -366,7 +235,7 @@
 	n=b-bl;
 	for (i=bl; i<b; i++)
 		ctx->buf[i]=n;
-	ret=ctx->cipher->do_cipher(ctx,out,ctx->buf,b);
+	ret=M_do_cipher(ctx,out,ctx->buf,b);
 
 
 	if(ret)
@@ -381,10 +250,10 @@
 	int fix_len;
 	unsigned int b;
 
-	if (inl == 0)
+	if (inl <= 0)
 		{
-		*outl=0;
-		return 1;
+		*outl = 0;
+		return inl == 0;
 		}
 
 	if (ctx->flags & EVP_CIPH_NO_PADDING)
@@ -488,28 +357,6 @@
 		}
 	}
 
-int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c)
-	{
-	if (c->cipher != NULL)
-		{
-		if(c->cipher->cleanup && !c->cipher->cleanup(c))
-			return 0;
-		/* Cleanse cipher context data */
-		if (c->cipher_data)
-			OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size);
-		}
-	if (c->cipher_data)
-		OPENSSL_free(c->cipher_data);
-#ifndef OPENSSL_NO_ENGINE
-	if (c->engine)
-		/* The EVP_CIPHER we used belongs to an ENGINE, release the
-		 * functional reference we held for this reason. */
-		ENGINE_finish(c->engine);
-#endif
-	memset(c,0,sizeof(EVP_CIPHER_CTX));
-	return 1;
-	}
-
 int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
 	{
 	if(c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) 
@@ -531,27 +378,6 @@
 	return 1;
 	}
 
-int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
-{
-	int ret;
-	if(!ctx->cipher) {
-		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET);
-		return 0;
-	}
-
-	if(!ctx->cipher->ctrl) {
-		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED);
-		return 0;
-	}
-
-	ret = ctx->cipher->ctrl(ctx, type, arg, ptr);
-	if(ret == -1) {
-		EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED);
-		return 0;
-	}
-	return ret;
-}
-
 int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key)
 	{
 	if (ctx->cipher->flags & EVP_CIPH_RAND_KEY)
@@ -561,3 +387,54 @@
 	return 1;
 	}
 
+#ifndef OPENSSL_NO_ENGINE
+
+#ifdef OPENSSL_FIPS
+
+static int do_evp_enc_engine_full(EVP_CIPHER_CTX *ctx, const EVP_CIPHER **pcipher, ENGINE *impl)
+	{
+	if(impl)
+		{
+		if (!ENGINE_init(impl))
+			{
+			EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATION_ERROR);
+			return 0;
+			}
+		}
+	else
+		/* Ask if an ENGINE is reserved for this job */
+		impl = ENGINE_get_cipher_engine((*pcipher)->nid);
+	if(impl)
+		{
+		/* There's an ENGINE for this job ... (apparently) */
+		const EVP_CIPHER *c = ENGINE_get_cipher(impl, (*pcipher)->nid);
+		if(!c)
+			{
+			/* One positive side-effect of US's export
+			 * control history, is that we should at least
+			 * be able to avoid using US mispellings of
+			 * "initialisation"? */
+			EVPerr(EVP_F_DO_EVP_ENC_ENGINE_FULL, EVP_R_INITIALIZATION_ERROR);
+			return 0;
+			}
+		/* We'll use the ENGINE's private cipher definition */
+		*pcipher = c;
+		/* Store the ENGINE functional reference so we know
+		 * 'cipher' came from an ENGINE and we need to release
+		 * it when done. */
+		ctx->engine = impl;
+		}
+	else
+		ctx->engine = NULL;
+	return 1;
+	}
+
+void int_EVP_CIPHER_init_engine_callbacks(void)
+	{
+	int_EVP_CIPHER_set_engine_callbacks(
+		ENGINE_finish, do_evp_enc_engine_full);
+	}
+
+#endif
+
+#endif
diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c
index e8c9e8d..b5b900d 100644
--- a/crypto/evp/evp_err.c
+++ b/crypto/evp/evp_err.c
@@ -1,6 +1,6 @@
 /* crypto/evp/evp_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2007 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
@@ -71,16 +71,23 @@
 static ERR_STRING_DATA EVP_str_functs[]=
 	{
 {ERR_FUNC(EVP_F_AES_INIT_KEY),	"AES_INIT_KEY"},
+{ERR_FUNC(EVP_F_ALG_MODULE_INIT),	"ALG_MODULE_INIT"},
 {ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY),	"CAMELLIA_INIT_KEY"},
 {ERR_FUNC(EVP_F_D2I_PKEY),	"D2I_PKEY"},
+{ERR_FUNC(EVP_F_DO_EVP_ENC_ENGINE),	"DO_EVP_ENC_ENGINE"},
+{ERR_FUNC(EVP_F_DO_EVP_ENC_ENGINE_FULL),	"DO_EVP_ENC_ENGINE_FULL"},
+{ERR_FUNC(EVP_F_DO_EVP_MD_ENGINE),	"DO_EVP_MD_ENGINE"},
+{ERR_FUNC(EVP_F_DO_EVP_MD_ENGINE_FULL),	"DO_EVP_MD_ENGINE_FULL"},
 {ERR_FUNC(EVP_F_DSAPKEY2PKCS8),	"DSAPKEY2PKCS8"},
 {ERR_FUNC(EVP_F_DSA_PKEY2PKCS8),	"DSA_PKEY2PKCS8"},
 {ERR_FUNC(EVP_F_ECDSA_PKEY2PKCS8),	"ECDSA_PKEY2PKCS8"},
 {ERR_FUNC(EVP_F_ECKEY_PKEY2PKCS8),	"ECKEY_PKEY2PKCS8"},
+{ERR_FUNC(EVP_F_EVP_CIPHERINIT),	"EVP_CipherInit"},
 {ERR_FUNC(EVP_F_EVP_CIPHERINIT_EX),	"EVP_CipherInit_ex"},
 {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_CTRL),	"EVP_CIPHER_CTX_ctrl"},
 {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH),	"EVP_CIPHER_CTX_set_key_length"},
 {ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX),	"EVP_DecryptFinal_ex"},
+{ERR_FUNC(EVP_F_EVP_DIGESTINIT),	"EVP_DigestInit"},
 {ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX),	"EVP_DigestInit_ex"},
 {ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX),	"EVP_EncryptFinal_ex"},
 {ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX),	"EVP_MD_CTX_copy_ex"},
@@ -125,15 +132,20 @@
 {ERR_REASON(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH),"data not multiple of block length"},
 {ERR_REASON(EVP_R_DECODE_ERROR)          ,"decode error"},
 {ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES)   ,"different key types"},
+{ERR_REASON(EVP_R_DISABLED_FOR_FIPS)     ,"disabled for fips"},
 {ERR_REASON(EVP_R_ENCODE_ERROR)          ,"encode error"},
+{ERR_REASON(EVP_R_ERROR_LOADING_SECTION) ,"error loading section"},
+{ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE),"error setting fips mode"},
 {ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR),"evp pbe cipherinit error"},
 {ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY)  ,"expecting an rsa key"},
 {ERR_REASON(EVP_R_EXPECTING_A_DH_KEY)    ,"expecting a dh key"},
 {ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY)   ,"expecting a dsa key"},
 {ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY) ,"expecting a ecdsa key"},
 {ERR_REASON(EVP_R_EXPECTING_A_EC_KEY)    ,"expecting a ec key"},
+{ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED),"fips mode not supported"},
 {ERR_REASON(EVP_R_INITIALIZATION_ERROR)  ,"initialization error"},
 {ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED) ,"input not initialized"},
+{ERR_REASON(EVP_R_INVALID_FIPS_MODE)     ,"invalid fips mode"},
 {ERR_REASON(EVP_R_INVALID_KEY_LENGTH)    ,"invalid key length"},
 {ERR_REASON(EVP_R_IV_TOO_LARGE)          ,"iv too large"},
 {ERR_REASON(EVP_R_KEYGEN_FAILURE)        ,"keygen failure"},
@@ -145,6 +157,8 @@
 {ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED),"no verify function configured"},
 {ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE),"pkcs8 unknown broken type"},
 {ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA)    ,"public key not rsa"},
+{ERR_REASON(EVP_R_SEED_KEY_SETUP_FAILED) ,"seed key setup failed"},
+{ERR_REASON(EVP_R_UNKNOWN_OPTION)        ,"unknown option"},
 {ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"},
 {ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"},
 {ERR_REASON(EVP_R_UNSUPPORTED_CIPHER)    ,"unsupported cipher"},
diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c
index edb28ef..174cf6c 100644
--- a/crypto/evp/evp_lib.c
+++ b/crypto/evp/evp_lib.c
@@ -67,6 +67,8 @@
 
 	if (c->cipher->set_asn1_parameters != NULL)
 		ret=c->cipher->set_asn1_parameters(c,type);
+	else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1)
+		ret=EVP_CIPHER_set_asn1_iv(c, type);
 	else
 		ret=-1;
 	return(ret);
@@ -78,6 +80,8 @@
 
 	if (c->cipher->get_asn1_parameters != NULL)
 		ret=c->cipher->get_asn1_parameters(c,type);
+	else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1)
+		ret=EVP_CIPHER_get_asn1_iv(c, type);
 	else
 		ret=-1;
 	return(ret);
@@ -178,11 +182,6 @@
 	return ctx->cipher->block_size;
 	}
 
-int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl)
-	{
-	return ctx->cipher->do_cipher(ctx,out,in,inl);
-	}
-
 const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx)
 	{
 	return ctx->cipher;
@@ -193,11 +192,6 @@
 	return cipher->flags;
 	}
 
-unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx)
-	{
-	return ctx->cipher->flags;
-	}
-
 void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx)
 	{
 	return ctx->app_data;
@@ -213,11 +207,6 @@
 	return cipher->iv_len;
 	}
 
-int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx)
-	{
-	return ctx->cipher->iv_len;
-	}
-
 int EVP_CIPHER_key_length(const EVP_CIPHER *cipher)
 	{
 	return cipher->key_len;
@@ -228,11 +217,6 @@
 	return ctx->key_len;
 	}
 
-int EVP_CIPHER_nid(const EVP_CIPHER *cipher)
-	{
-	return cipher->nid;
-	}
-
 int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
 	{
 	return ctx->cipher->nid;
@@ -277,3 +261,18 @@
 	{
 	return (ctx->flags & flags);
 	}
+
+void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags)
+	{
+	ctx->flags |= flags;
+	}
+
+void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags)
+	{
+	ctx->flags &= ~flags;
+	}
+
+int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags)
+	{
+	return (ctx->flags & flags);
+	}
diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h
index 073b0ad..eabcc96 100644
--- a/crypto/evp/evp_locl.h
+++ b/crypto/evp/evp_locl.h
@@ -1,5 +1,5 @@
 /* evp_locl.h */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
@@ -92,7 +92,7 @@
 #define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \
 static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, unsigned int inl) \
 {\
-	cprefix##_cfb##cbits##_encrypt(in, out, (long)(cbits==1?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\
+	cprefix##_cfb##cbits##_encrypt(in, out, (long)((cbits==1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\
 	return 1;\
 }
 
@@ -226,11 +226,27 @@
 
 #define EVP_C_DATA(kstruct, ctx)	((kstruct *)(ctx)->cipher_data)
 
-#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len) \
+#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len,fl) \
 	BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \
 	BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \
 			     NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \
-			     0, cipher##_init_key, NULL, \
-			     EVP_CIPHER_set_asn1_iv, \
-			     EVP_CIPHER_get_asn1_iv, \
-			     NULL)
+			     (fl)|EVP_CIPH_FLAG_DEFAULT_ASN1, \
+			     cipher##_init_key, NULL, NULL, NULL, NULL)
+
+#ifdef OPENSSL_FIPS
+#define RC2_set_key	private_RC2_set_key
+#define RC4_set_key	private_RC4_set_key
+#define CAST_set_key	private_CAST_set_key
+#define RC5_32_set_key	private_RC5_32_set_key
+#define BF_set_key	private_BF_set_key
+#define Camellia_set_key private_Camellia_set_key
+#define idea_set_encrypt_key private_idea_set_encrypt_key
+
+#define MD5_Init	private_MD5_Init
+#define MD4_Init	private_MD4_Init
+#define MD2_Init	private_MD2_Init
+#define MDC2_Init	private_MDC2_Init
+#define SHA_Init	private_SHA_Init
+
+#endif
+
diff --git a/crypto/evp/evp_pbe.c b/crypto/evp/evp_pbe.c
index c26d2de..5e830be 100644
--- a/crypto/evp/evp_pbe.c
+++ b/crypto/evp/evp_pbe.c
@@ -1,5 +1,5 @@
 /* evp_pbe.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/evp/evp_pkey.c b/crypto/evp/evp_pkey.c
index 0147f3e..10d9e9e 100644
--- a/crypto/evp/evp_pkey.c
+++ b/crypto/evp/evp_pkey.c
@@ -1,5 +1,5 @@
 /* evp_pkey.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/evp/evp_test.c b/crypto/evp/evp_test.c
index bb6f02c..436be20 100644
--- a/crypto/evp/evp_test.c
+++ b/crypto/evp/evp_test.c
@@ -220,18 +220,18 @@
 	    test1_exit(7);
 	    }
 
-	if(outl+outl2 != cn)
+	if(outl+outl2 != pn)
 	    {
 	    fprintf(stderr,"Plaintext length mismatch got %d expected %d\n",
-		    outl+outl2,cn);
+		    outl+outl2,pn);
 	    test1_exit(8);
 	    }
 
-	if(memcmp(out,plaintext,cn))
+	if(memcmp(out,plaintext,pn))
 	    {
 	    fprintf(stderr,"Plaintext mismatch\n");
-	    hexdump(stderr,"Got",out,cn);
-	    hexdump(stderr,"Expected",plaintext,cn);
+	    hexdump(stderr,"Got",out,pn);
+	    hexdump(stderr,"Expected",plaintext,pn);
 	    test1_exit(9);
 	    }
 	}
diff --git a/crypto/evp/m_dss.c b/crypto/evp/m_dss.c
index a948c77..6b0c0aa 100644
--- a/crypto/evp/m_dss.c
+++ b/crypto/evp/m_dss.c
@@ -81,7 +81,7 @@
 	NID_dsaWithSHA,
 	NID_dsaWithSHA,
 	SHA_DIGEST_LENGTH,
-	0,
+	EVP_MD_FLAG_FIPS,
 	init,
 	update,
 	final,
diff --git a/crypto/evp/m_dss1.c b/crypto/evp/m_dss1.c
index c12e139..da8babc 100644
--- a/crypto/evp/m_dss1.c
+++ b/crypto/evp/m_dss1.c
@@ -68,6 +68,8 @@
 #include <openssl/dsa.h>
 #endif
 
+#ifndef OPENSSL_FIPS
+
 static int init(EVP_MD_CTX *ctx)
 	{ return SHA1_Init(ctx->md_data); }
 
@@ -98,3 +100,4 @@
 	return(&dss1_md);
 	}
 #endif
+#endif
diff --git a/crypto/evp/m_md2.c b/crypto/evp/m_md2.c
index 5ce849f..8eee623 100644
--- a/crypto/evp/m_md2.c
+++ b/crypto/evp/m_md2.c
@@ -58,6 +58,7 @@
 
 #include <stdio.h>
 #include "cryptlib.h"
+#include "evp_locl.h"
 
 #ifndef OPENSSL_NO_MD2
 
diff --git a/crypto/evp/m_md4.c b/crypto/evp/m_md4.c
index 1e0b7c5..5cd2ab5 100644
--- a/crypto/evp/m_md4.c
+++ b/crypto/evp/m_md4.c
@@ -58,6 +58,7 @@
 
 #include <stdio.h>
 #include "cryptlib.h"
+#include "evp_locl.h"
 
 #ifndef OPENSSL_NO_MD4
 
diff --git a/crypto/evp/m_md5.c b/crypto/evp/m_md5.c
index 63c1421..6455829 100644
--- a/crypto/evp/m_md5.c
+++ b/crypto/evp/m_md5.c
@@ -62,6 +62,7 @@
 #ifndef OPENSSL_NO_MD5
 
 #include <openssl/evp.h>
+#include "evp_locl.h"
 #include <openssl/objects.h>
 #include <openssl/x509.h>
 #include <openssl/md5.h>
diff --git a/crypto/evp/m_mdc2.c b/crypto/evp/m_mdc2.c
index 36c4e9b..9f9bcf0 100644
--- a/crypto/evp/m_mdc2.c
+++ b/crypto/evp/m_mdc2.c
@@ -58,6 +58,7 @@
 
 #include <stdio.h>
 #include "cryptlib.h"
+#include "evp_locl.h"
 
 #ifndef OPENSSL_NO_MDC2
 
diff --git a/crypto/evp/m_sha.c b/crypto/evp/m_sha.c
index acccc8f..3f30dfc 100644
--- a/crypto/evp/m_sha.c
+++ b/crypto/evp/m_sha.c
@@ -58,6 +58,7 @@
 
 #include <stdio.h>
 #include "cryptlib.h"
+#include "evp_locl.h"
 
 #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0)
 
diff --git a/crypto/evp/m_sha1.c b/crypto/evp/m_sha1.c
index 4679b1c..471ec30 100644
--- a/crypto/evp/m_sha1.c
+++ b/crypto/evp/m_sha1.c
@@ -68,6 +68,8 @@
 #include <openssl/rsa.h>
 #endif
 
+#ifndef OPENSSL_FIPS
+
 static int init(EVP_MD_CTX *ctx)
 	{ return SHA1_Init(ctx->md_data); }
 
@@ -97,7 +99,6 @@
 	{
 	return(&sha1_md);
 	}
-#endif
 
 #ifndef OPENSSL_NO_SHA256
 static int init224(EVP_MD_CTX *ctx)
@@ -202,3 +203,7 @@
 const EVP_MD *EVP_sha512(void)
 	{ return(&sha512_md); }
 #endif	/* ifndef OPENSSL_NO_SHA512 */
+
+#endif
+
+#endif
diff --git a/crypto/evp/names.c b/crypto/evp/names.c
index 88c1e78..e2e04c3 100644
--- a/crypto/evp/names.c
+++ b/crypto/evp/names.c
@@ -66,6 +66,10 @@
 	{
 	int r;
 
+#ifdef OPENSSL_FIPS
+	OPENSSL_init();
+#endif
+
 	r=OBJ_NAME_add(OBJ_nid2sn(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c);
 	if (r == 0) return(0);
 	r=OBJ_NAME_add(OBJ_nid2ln(c->nid),OBJ_NAME_TYPE_CIPHER_METH,(const char *)c);
@@ -77,6 +81,9 @@
 	int r;
 	const char *name;
 
+#ifdef OPENSSL_FIPS
+	OPENSSL_init();
+#endif
 	name=OBJ_nid2sn(md->type);
 	r=OBJ_NAME_add(name,OBJ_NAME_TYPE_MD_METH,(const char *)md);
 	if (r == 0) return(0);
diff --git a/crypto/evp/p5_crpt.c b/crypto/evp/p5_crpt.c
index 48d5001..2a265fd 100644
--- a/crypto/evp/p5_crpt.c
+++ b/crypto/evp/p5_crpt.c
@@ -1,5 +1,5 @@
 /* p5_crpt.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/evp/p5_crpt2.c b/crypto/evp/p5_crpt2.c
index c969d5a..6bec77b 100644
--- a/crypto/evp/p5_crpt2.c
+++ b/crypto/evp/p5_crpt2.c
@@ -1,5 +1,5 @@
 /* p5_crpt2.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/evp/p_sign.c b/crypto/evp/p_sign.c
index e4ae590..bf41a0d 100644
--- a/crypto/evp/p_sign.c
+++ b/crypto/evp/p_sign.c
@@ -84,10 +84,6 @@
 	MS_STATIC EVP_MD_CTX tmp_ctx;
 
 	*siglen=0;
-	EVP_MD_CTX_init(&tmp_ctx);
-	EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);   
-	EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
-	EVP_MD_CTX_cleanup(&tmp_ctx);
 	for (i=0; i<4; i++)
 		{
 		v=ctx->digest->required_pkey_type[i];
@@ -108,7 +104,23 @@
 		EVPerr(EVP_F_EVP_SIGNFINAL,EVP_R_NO_SIGN_FUNCTION_CONFIGURED);
 		return(0);
 		}
-	return(ctx->digest->sign(ctx->digest->type,m,m_len,sigret,siglen,
-		pkey->pkey.ptr));
+	EVP_MD_CTX_init(&tmp_ctx);
+	EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);
+	if (ctx->digest->flags & EVP_MD_FLAG_SVCTX)
+		{
+		EVP_MD_SVCTX sctmp;
+		sctmp.mctx = &tmp_ctx;
+		sctmp.key = pkey->pkey.ptr;
+		i = ctx->digest->sign(ctx->digest->type,
+			NULL, -1, sigret, siglen, &sctmp);
+		}
+	else
+		{
+		EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
+		i = ctx->digest->sign(ctx->digest->type,m,m_len,sigret,siglen,
+					pkey->pkey.ptr);
+		}
+	EVP_MD_CTX_cleanup(&tmp_ctx);
+	return i;
 	}
 
diff --git a/crypto/evp/p_verify.c b/crypto/evp/p_verify.c
index 21a40a3..2d46dff 100644
--- a/crypto/evp/p_verify.c
+++ b/crypto/evp/p_verify.c
@@ -85,17 +85,29 @@
 		EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_WRONG_PUBLIC_KEY_TYPE);
 		return(-1);
 		}
-	EVP_MD_CTX_init(&tmp_ctx);
-	EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);     
-	EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
-	EVP_MD_CTX_cleanup(&tmp_ctx);
-        if (ctx->digest->verify == NULL)
+	if (ctx->digest->verify == NULL)
                 {
 		EVPerr(EVP_F_EVP_VERIFYFINAL,EVP_R_NO_VERIFY_FUNCTION_CONFIGURED);
 		return(0);
 		}
 
-	return(ctx->digest->verify(ctx->digest->type,m,m_len,
-		sigbuf,siglen,pkey->pkey.ptr));
+	EVP_MD_CTX_init(&tmp_ctx);
+	EVP_MD_CTX_copy_ex(&tmp_ctx,ctx);     
+	if (ctx->digest->flags & EVP_MD_FLAG_SVCTX)
+		{
+		EVP_MD_SVCTX sctmp;
+		sctmp.mctx = &tmp_ctx;
+		sctmp.key = pkey->pkey.ptr;
+		i = ctx->digest->verify(ctx->digest->type,
+			NULL, -1, sigbuf, siglen, &sctmp);
+		}
+	else
+		{
+		EVP_DigestFinal_ex(&tmp_ctx,&(m[0]),&m_len);
+		i = ctx->digest->verify(ctx->digest->type,m,m_len,
+					sigbuf,siglen,pkey->pkey.ptr);
+		}
+	EVP_MD_CTX_cleanup(&tmp_ctx);
+	return i;
 	}
 
diff --git a/crypto/fips_err.c b/crypto/fips_err.c
new file mode 100644
index 0000000..09f1174
--- /dev/null
+++ b/crypto/fips_err.c
@@ -0,0 +1,7 @@
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_FIPS
+# include "fips_err.h"
+#else
+static void *dummy=&dummy;
+#endif
diff --git a/crypto/fips_err.h b/crypto/fips_err.h
new file mode 100644
index 0000000..b328616
--- /dev/null
+++ b/crypto/fips_err.h
@@ -0,0 +1,137 @@
+/* crypto/fips_err.h */
+/* ====================================================================
+ * Copyright (c) 1999-2007 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/fips.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_FIPS,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_FIPS,0,reason)
+
+static ERR_STRING_DATA FIPS_str_functs[]=
+	{
+{ERR_FUNC(FIPS_F_DH_BUILTIN_GENPARAMS),	"DH_BUILTIN_GENPARAMS"},
+{ERR_FUNC(FIPS_F_DSA_BUILTIN_PARAMGEN),	"DSA_BUILTIN_PARAMGEN"},
+{ERR_FUNC(FIPS_F_DSA_DO_SIGN),	"DSA_do_sign"},
+{ERR_FUNC(FIPS_F_DSA_DO_VERIFY),	"DSA_do_verify"},
+{ERR_FUNC(FIPS_F_EVP_CIPHERINIT_EX),	"EVP_CipherInit_ex"},
+{ERR_FUNC(FIPS_F_EVP_DIGESTINIT_EX),	"EVP_DigestInit_ex"},
+{ERR_FUNC(FIPS_F_FIPS_CHECK_DSA),	"FIPS_CHECK_DSA"},
+{ERR_FUNC(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT),	"FIPS_CHECK_INCORE_FINGERPRINT"},
+{ERR_FUNC(FIPS_F_FIPS_CHECK_RSA),	"FIPS_CHECK_RSA"},
+{ERR_FUNC(FIPS_F_FIPS_DSA_CHECK),	"FIPS_DSA_CHECK"},
+{ERR_FUNC(FIPS_F_FIPS_MODE_SET),	"FIPS_mode_set"},
+{ERR_FUNC(FIPS_F_FIPS_PKEY_SIGNATURE_TEST),	"fips_pkey_signature_test"},
+{ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES),	"FIPS_selftest_aes"},
+{ERR_FUNC(FIPS_F_FIPS_SELFTEST_DES),	"FIPS_selftest_des"},
+{ERR_FUNC(FIPS_F_FIPS_SELFTEST_DSA),	"FIPS_selftest_dsa"},
+{ERR_FUNC(FIPS_F_FIPS_SELFTEST_HMAC),	"FIPS_selftest_hmac"},
+{ERR_FUNC(FIPS_F_FIPS_SELFTEST_RNG),	"FIPS_selftest_rng"},
+{ERR_FUNC(FIPS_F_FIPS_SELFTEST_SHA1),	"FIPS_selftest_sha1"},
+{ERR_FUNC(FIPS_F_HASH_FINAL),	"HASH_FINAL"},
+{ERR_FUNC(FIPS_F_RSA_BUILTIN_KEYGEN),	"RSA_BUILTIN_KEYGEN"},
+{ERR_FUNC(FIPS_F_RSA_EAY_PRIVATE_DECRYPT),	"RSA_EAY_PRIVATE_DECRYPT"},
+{ERR_FUNC(FIPS_F_RSA_EAY_PRIVATE_ENCRYPT),	"RSA_EAY_PRIVATE_ENCRYPT"},
+{ERR_FUNC(FIPS_F_RSA_EAY_PUBLIC_DECRYPT),	"RSA_EAY_PUBLIC_DECRYPT"},
+{ERR_FUNC(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT),	"RSA_EAY_PUBLIC_ENCRYPT"},
+{ERR_FUNC(FIPS_F_RSA_X931_GENERATE_KEY_EX),	"RSA_X931_generate_key_ex"},
+{ERR_FUNC(FIPS_F_SSLEAY_RAND_BYTES),	"SSLEAY_RAND_BYTES"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA FIPS_str_reasons[]=
+	{
+{ERR_REASON(FIPS_R_CANNOT_READ_EXE)      ,"cannot read exe"},
+{ERR_REASON(FIPS_R_CANNOT_READ_EXE_DIGEST),"cannot read exe digest"},
+{ERR_REASON(FIPS_R_CONTRADICTING_EVIDENCE),"contradicting evidence"},
+{ERR_REASON(FIPS_R_EXE_DIGEST_DOES_NOT_MATCH),"exe digest does not match"},
+{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH),"fingerprint does not match"},
+{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED),"fingerprint does not match nonpic relocated"},
+{ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING),"fingerprint does not match segment aliasing"},
+{ERR_REASON(FIPS_R_FIPS_MODE_ALREADY_SET),"fips mode already set"},
+{ERR_REASON(FIPS_R_FIPS_SELFTEST_FAILED) ,"fips selftest failed"},
+{ERR_REASON(FIPS_R_INVALID_KEY_LENGTH)   ,"invalid key length"},
+{ERR_REASON(FIPS_R_KEY_TOO_SHORT)        ,"key too short"},
+{ERR_REASON(FIPS_R_NON_FIPS_METHOD)      ,"non fips method"},
+{ERR_REASON(FIPS_R_PAIRWISE_TEST_FAILED) ,"pairwise test failed"},
+{ERR_REASON(FIPS_R_RSA_DECRYPT_ERROR)    ,"rsa decrypt error"},
+{ERR_REASON(FIPS_R_RSA_ENCRYPT_ERROR)    ,"rsa encrypt error"},
+{ERR_REASON(FIPS_R_SELFTEST_FAILED)      ,"selftest failed"},
+{ERR_REASON(FIPS_R_TEST_FAILURE)         ,"test failure"},
+{ERR_REASON(FIPS_R_UNSUPPORTED_PLATFORM) ,"unsupported platform"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_FIPS_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(FIPS_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,FIPS_str_functs);
+		ERR_load_strings(0,FIPS_str_reasons);
+		}
+#endif
+	}
diff --git a/crypto/hmac/Makefile b/crypto/hmac/Makefile
index 01f10c3..5cfa37d 100644
--- a/crypto/hmac/Makefile
+++ b/crypto/hmac/Makefile
@@ -33,7 +33,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -77,9 +77,10 @@
 hmac.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 hmac.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 hmac.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-hmac.o: ../../include/openssl/evp.h ../../include/openssl/hmac.h
-hmac.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-hmac.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-hmac.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-hmac.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-hmac.o: ../../include/openssl/symhacks.h ../cryptlib.h hmac.c
+hmac.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+hmac.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+hmac.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+hmac.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+hmac.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+hmac.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+hmac.o: ../cryptlib.h hmac.c
diff --git a/crypto/hmac/hmac.c b/crypto/hmac/hmac.c
index c45e001..cbc1c76 100644
--- a/crypto/hmac/hmac.c
+++ b/crypto/hmac/hmac.c
@@ -61,6 +61,8 @@
 #include "cryptlib.h"
 #include <openssl/hmac.h>
 
+#ifndef OPENSSL_FIPS
+
 void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
 		  const EVP_MD *md, ENGINE *impl)
 	{
@@ -171,3 +173,11 @@
 	return(md);
 	}
 
+void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags)
+	{
+	EVP_MD_CTX_set_flags(&ctx->i_ctx, flags);
+	EVP_MD_CTX_set_flags(&ctx->o_ctx, flags);
+	EVP_MD_CTX_set_flags(&ctx->md_ctx, flags);
+	}
+
+#endif
diff --git a/crypto/hmac/hmac.h b/crypto/hmac/hmac.h
index 719fc40..fc38ffb 100644
--- a/crypto/hmac/hmac.h
+++ b/crypto/hmac/hmac.h
@@ -100,6 +100,7 @@
 		    const unsigned char *d, size_t n, unsigned char *md,
 		    unsigned int *md_len);
 
+void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags);
 
 #ifdef  __cplusplus
 }
diff --git a/crypto/install.com b/crypto/install.com
index 58a4fec..ffad1f9 100644
--- a/crypto/install.com
+++ b/crypto/install.com
@@ -35,12 +35,12 @@
 $	SDIRS := ,-
 		 OBJECTS,-
 		 MD2,MD4,MD5,SHA,MDC2,HMAC,RIPEMD,-
-		 DES,RC2,RC4,RC5,IDEA,BF,CAST,CAMELLIA,SEED,-
-		 BN,EC,RSA,DSA,ECDSA,DH,ECDH,DSO,ENGINE,AES,-
+		 DES,AES,RC2,RC4,RC5,IDEA,BF,CAST,CAMELLIA,SEED,-
+		 BN,EC,RSA,DSA,ECDSA,DH,ECDH,DSO,ENGINE,-
 		 BUFFER,BIO,STACK,LHASH,RAND,ERR,-
 		 EVP,ASN1,PEM,X509,X509V3,CONF,TXT_DB,PKCS7,PKCS12,COMP,OCSP,-
 		 UI,KRB5,-
-		 STORE,CMS,PQUEUE
+		 STORE,PQUEUE,JPAKE
 $	EXHEADER_ := crypto.h,tmdiff.h,opensslv.h,opensslconf.h,ebcdic.h,-
 		symhacks.h,ossl_typ.h
 $	EXHEADER_OBJECTS := objects.h,obj_mac.h
@@ -52,6 +52,7 @@
 $	EXHEADER_HMAC := hmac.h
 $	EXHEADER_RIPEMD := ripemd.h
 $	EXHEADER_DES := des.h,des_old.h
+$	EXHEADER_AES := aes.h
 $	EXHEADER_RC2 := rc2.h
 $	EXHEADER_RC4 := rc4.h
 $	EXHEADER_RC5 := rc5.h
@@ -69,7 +70,6 @@
 $	EXHEADER_ECDH := ecdh.h
 $	EXHEADER_DSO := dso.h
 $	EXHEADER_ENGINE := engine.h
-$	EXHEADER_AES := aes.h
 $	EXHEADER_BUFFER := buffer.h
 $	EXHEADER_BIO := bio.h
 $	EXHEADER_STACK := stack.h,safestack.h
@@ -92,7 +92,7 @@
 $!	EXHEADER_STORE := store.h,str_compat.h
 $	EXHEADER_STORE := store.h
 $	EXHEADER_PQUEUE := pqueue.h,pq_compat.h
-$	EXHEADER_CMS := cms.h
+$	EXHEADER_JPAKE := jpake.h
 $	LIBS := LIBCRYPTO
 $
 $	VEXE_DIR := [-.VAX.EXE.CRYPTO]
diff --git a/crypto/jpake/Makefile b/crypto/jpake/Makefile
new file mode 100644
index 0000000..a4a1402
--- /dev/null
+++ b/crypto/jpake/Makefile
@@ -0,0 +1,64 @@
+DIR=jpake
+TOP=../..
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+LIB=$(TOP)/libcrypto.a
+LIBOBJ=jpake.o jpake_err.o
+LIBSRC=jpake.c jpake_err.c
+
+EXHEADER=jpake.h
+TEST=jpaketest.c
+
+top:
+	(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all:	lib
+
+lib:	$(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
+	$(RANLIB) $(LIB) || echo Never mind.
+	@touch lib
+
+links:
+	@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+	@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+
+install:
+	@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+	@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
+	do  \
+	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+	done;
+
+depend:
+	@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
+	$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
+
+dclean:
+	$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+	mv -f Makefile.new $(MAKEFILE)
+
+clean:
+	rm -f *.s *.o *.obj des lib tags core .pure .nfs* *.old *.bak fluff
+
+jpaketest: top jpaketest.c $(LIB)
+	$(CC) $(CFLAGS) -Wall -Werror -g -o jpaketest jpaketest.c $(LIB)
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+jpake.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+jpake.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+jpake.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+jpake.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+jpake.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+jpake.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+jpake.o: ../../include/openssl/symhacks.h jpake.c jpake.h
+jpake_err.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+jpake_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+jpake_err.o: ../../include/openssl/err.h ../../include/openssl/jpake.h
+jpake_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+jpake_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+jpake_err.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+jpake_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+jpake_err.o: jpake_err.c
diff --git a/crypto/jpake/jpake.c b/crypto/jpake/jpake.c
new file mode 100644
index 0000000..577b7ef
--- /dev/null
+++ b/crypto/jpake/jpake.c
@@ -0,0 +1,483 @@
+#include "jpake.h"
+
+#include <openssl/crypto.h>
+#include <openssl/sha.h>
+#include <openssl/err.h>
+#include <memory.h>
+#include <assert.h>
+
+/*
+ * In the definition, (xa, xb, xc, xd) are Alice's (x1, x2, x3, x4) or
+ * Bob's (x3, x4, x1, x2). If you see what I mean.
+ */
+
+typedef struct
+    {
+    char *name;  /* Must be unique */
+    char *peer_name;
+    BIGNUM *p;
+    BIGNUM *g;
+    BIGNUM *q;
+    BIGNUM *gxc; /* Alice's g^{x3} or Bob's g^{x1} */
+    BIGNUM *gxd; /* Alice's g^{x4} or Bob's g^{x2} */
+    } JPAKE_CTX_PUBLIC;
+
+struct JPAKE_CTX
+    {
+    JPAKE_CTX_PUBLIC p;
+    BIGNUM *secret;   /* The shared secret */
+    BN_CTX *ctx;
+    BIGNUM *xa;       /* Alice's x1 or Bob's x3 */
+    BIGNUM *xb;       /* Alice's x2 or Bob's x4 */
+    BIGNUM *key;      /* The calculated (shared) key */
+    };
+
+static void JPAKE_ZKP_init(JPAKE_ZKP *zkp)
+    {
+    zkp->gr = BN_new();
+    zkp->b = BN_new();
+    }
+
+static void JPAKE_ZKP_release(JPAKE_ZKP *zkp)
+    {
+    BN_free(zkp->b);
+    BN_free(zkp->gr);
+    }
+
+/* Two birds with one stone - make the global name as expected */
+#define JPAKE_STEP_PART_init	JPAKE_STEP2_init
+#define JPAKE_STEP_PART_release	JPAKE_STEP2_release
+
+void JPAKE_STEP_PART_init(JPAKE_STEP_PART *p)
+    {
+    p->gx = BN_new();
+    JPAKE_ZKP_init(&p->zkpx);
+    }
+
+void JPAKE_STEP_PART_release(JPAKE_STEP_PART *p)
+    {
+    JPAKE_ZKP_release(&p->zkpx);
+    BN_free(p->gx);
+    }
+
+void JPAKE_STEP1_init(JPAKE_STEP1 *s1)
+    {
+    JPAKE_STEP_PART_init(&s1->p1);
+    JPAKE_STEP_PART_init(&s1->p2);
+    }
+
+void JPAKE_STEP1_release(JPAKE_STEP1 *s1)
+    {
+    JPAKE_STEP_PART_release(&s1->p2);
+    JPAKE_STEP_PART_release(&s1->p1);
+    }
+
+static void JPAKE_CTX_init(JPAKE_CTX *ctx, const char *name,
+			   const char *peer_name, const BIGNUM *p,
+			   const BIGNUM *g, const BIGNUM *q,
+			   const BIGNUM *secret)
+    {
+    ctx->p.name = OPENSSL_strdup(name);
+    ctx->p.peer_name = OPENSSL_strdup(peer_name);
+    ctx->p.p = BN_dup(p);
+    ctx->p.g = BN_dup(g);
+    ctx->p.q = BN_dup(q);
+    ctx->secret = BN_dup(secret);
+
+    ctx->p.gxc = BN_new();
+    ctx->p.gxd = BN_new();
+
+    ctx->xa = BN_new();
+    ctx->xb = BN_new();
+    ctx->key = BN_new();
+    ctx->ctx = BN_CTX_new();
+    }
+    
+static void JPAKE_CTX_release(JPAKE_CTX *ctx)
+    {
+    BN_CTX_free(ctx->ctx);
+    BN_clear_free(ctx->key);
+    BN_clear_free(ctx->xb);
+    BN_clear_free(ctx->xa);
+
+    BN_free(ctx->p.gxd);
+    BN_free(ctx->p.gxc);
+
+    BN_clear_free(ctx->secret);
+    BN_free(ctx->p.q);
+    BN_free(ctx->p.g);
+    BN_free(ctx->p.p);
+    OPENSSL_free(ctx->p.peer_name);
+    OPENSSL_free(ctx->p.name);
+
+    memset(ctx, '\0', sizeof *ctx);
+    }
+    
+JPAKE_CTX *JPAKE_CTX_new(const char *name, const char *peer_name,
+			 const BIGNUM *p, const BIGNUM *g, const BIGNUM *q,
+			 const BIGNUM *secret)
+    {
+    JPAKE_CTX *ctx = OPENSSL_malloc(sizeof *ctx);
+
+    JPAKE_CTX_init(ctx, name, peer_name, p, g, q, secret);
+
+    return ctx;
+    }
+
+void JPAKE_CTX_free(JPAKE_CTX *ctx)
+    {
+    JPAKE_CTX_release(ctx);
+    OPENSSL_free(ctx);
+    }
+
+static void hashlength(SHA_CTX *sha, size_t l)
+    {
+    unsigned char b[2];
+
+    assert(l <= 0xffff);
+    b[0] = l >> 8;
+    b[1] = l&0xff;
+    SHA1_Update(sha, b, 2);
+    }
+
+static void hashstring(SHA_CTX *sha, const char *string)
+    {
+    size_t l = strlen(string);
+
+    hashlength(sha, l);
+    SHA1_Update(sha, string, l);
+    }
+
+static void hashbn(SHA_CTX *sha, const BIGNUM *bn)
+    {
+    size_t l = BN_num_bytes(bn);
+    unsigned char *bin = OPENSSL_malloc(l);
+
+    hashlength(sha, l);
+    BN_bn2bin(bn, bin);
+    SHA1_Update(sha, bin, l);
+    OPENSSL_free(bin);
+    }
+
+/* h=hash(g, g^r, g^x, name) */
+static void zkp_hash(BIGNUM *h, const BIGNUM *zkpg, const JPAKE_STEP_PART *p,
+		     const char *proof_name)
+    {
+    unsigned char md[SHA_DIGEST_LENGTH];
+    SHA_CTX sha;
+
+   /*
+    * XXX: hash should not allow moving of the boundaries - Java code
+    * is flawed in this respect. Length encoding seems simplest.
+    */
+    SHA1_Init(&sha);
+    hashbn(&sha, zkpg);
+    assert(!BN_is_zero(p->zkpx.gr));
+    hashbn(&sha, p->zkpx.gr);
+    hashbn(&sha, p->gx);
+    hashstring(&sha, proof_name);
+    SHA1_Final(md, &sha);
+    BN_bin2bn(md, SHA_DIGEST_LENGTH, h);
+    }
+
+/*
+ * Prove knowledge of x
+ * Note that p->gx has already been calculated
+ */
+static void generate_zkp(JPAKE_STEP_PART *p, const BIGNUM *x,
+			 const BIGNUM *zkpg, JPAKE_CTX *ctx)
+    {
+    BIGNUM *r = BN_new();
+    BIGNUM *h = BN_new();
+    BIGNUM *t = BN_new();
+
+   /*
+    * r in [0,q)
+    * XXX: Java chooses r in [0, 2^160) - i.e. distribution not uniform
+    */
+    BN_rand_range(r, ctx->p.q);
+   /* g^r */
+    BN_mod_exp(p->zkpx.gr, zkpg, r, ctx->p.p, ctx->ctx);
+
+   /* h=hash... */
+    zkp_hash(h, zkpg, p, ctx->p.name);
+
+   /* b = r - x*h */
+    BN_mod_mul(t, x, h, ctx->p.q, ctx->ctx);
+    BN_mod_sub(p->zkpx.b, r, t, ctx->p.q, ctx->ctx);
+
+   /* cleanup */
+    BN_free(t);
+    BN_free(h);
+    BN_free(r);
+    }
+
+static int verify_zkp(const JPAKE_STEP_PART *p, const BIGNUM *zkpg,
+		      JPAKE_CTX *ctx)
+    {
+    BIGNUM *h = BN_new();
+    BIGNUM *t1 = BN_new();
+    BIGNUM *t2 = BN_new();
+    BIGNUM *t3 = BN_new();
+    int ret = 0;
+
+    zkp_hash(h, zkpg, p, ctx->p.peer_name);
+
+   /* t1 = g^b */
+    BN_mod_exp(t1, zkpg, p->zkpx.b, ctx->p.p, ctx->ctx);
+   /* t2 = (g^x)^h = g^{hx} */
+    BN_mod_exp(t2, p->gx, h, ctx->p.p, ctx->ctx);
+   /* t3 = t1 * t2 = g^{hx} * g^b = g^{hx+b} = g^r (allegedly) */
+    BN_mod_mul(t3, t1, t2, ctx->p.p, ctx->ctx);
+
+   /* verify t3 == g^r */
+    if(BN_cmp(t3, p->zkpx.gr) == 0)
+	ret = 1;
+    else
+	JPAKEerr(JPAKE_F_VERIFY_ZKP, JPAKE_R_ZKP_VERIFY_FAILED);
+
+   /* cleanup */
+    BN_free(t3);
+    BN_free(t2);
+    BN_free(t1);
+    BN_free(h);
+
+    return ret;
+    }    
+
+static void generate_step_part(JPAKE_STEP_PART *p, const BIGNUM *x,
+			       const BIGNUM *g, JPAKE_CTX *ctx)
+    {
+    BN_mod_exp(p->gx, g, x, ctx->p.p, ctx->ctx);
+    generate_zkp(p, x, g, ctx);
+    }
+
+/* Generate each party's random numbers. xa is in [0, q), xb is in [1, q). */
+static void genrand(JPAKE_CTX *ctx)
+    {
+    BIGNUM *qm1;
+
+   /* xa in [0, q) */
+    BN_rand_range(ctx->xa, ctx->p.q);
+
+   /* q-1 */
+    qm1 = BN_new();
+    BN_copy(qm1, ctx->p.q);
+    BN_sub_word(qm1, 1);
+
+   /* ... and xb in [0, q-1) */
+    BN_rand_range(ctx->xb, qm1);
+   /* [1, q) */
+    BN_add_word(ctx->xb, 1);
+
+   /* cleanup */
+    BN_free(qm1);
+    }
+
+int JPAKE_STEP1_generate(JPAKE_STEP1 *send, JPAKE_CTX *ctx)
+    {
+    genrand(ctx);
+    generate_step_part(&send->p1, ctx->xa, ctx->p.g, ctx);
+    generate_step_part(&send->p2, ctx->xb, ctx->p.g, ctx);
+
+    return 1;
+    }
+
+int JPAKE_STEP1_process(JPAKE_CTX *ctx, const JPAKE_STEP1 *received)
+    {
+   /* verify their ZKP(xc) */
+    if(!verify_zkp(&received->p1, ctx->p.g, ctx))
+	{
+	JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X3_FAILED);
+	return 0;
+	}
+
+   /* verify their ZKP(xd) */
+    if(!verify_zkp(&received->p2, ctx->p.g, ctx))
+	{
+	JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X4_FAILED);
+	return 0;
+	}
+
+   /* g^xd != 1 */
+    if(BN_is_one(received->p2.gx))
+	{
+	JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_ONE);
+	return 0;
+	}
+
+   /* Save the bits we need for later */
+    BN_copy(ctx->p.gxc, received->p1.gx);
+    BN_copy(ctx->p.gxd, received->p2.gx);
+
+    return 1;
+    }
+
+
+int JPAKE_STEP2_generate(JPAKE_STEP2 *send, JPAKE_CTX *ctx)
+    {
+    BIGNUM *t1 = BN_new();
+    BIGNUM *t2 = BN_new();
+
+   /*
+    * X = g^{(xa + xc + xd) * xb * s}
+    * t1 = g^xa
+    */
+    BN_mod_exp(t1, ctx->p.g, ctx->xa, ctx->p.p, ctx->ctx);
+   /* t2 = t1 * g^{xc} = g^{xa} * g^{xc} = g^{xa + xc} */
+    BN_mod_mul(t2, t1, ctx->p.gxc, ctx->p.p, ctx->ctx);
+   /* t1 = t2 * g^{xd} = g^{xa + xc + xd} */
+    BN_mod_mul(t1, t2, ctx->p.gxd, ctx->p.p, ctx->ctx);
+   /* t2 = xb * s */
+    BN_mod_mul(t2, ctx->xb, ctx->secret, ctx->p.q, ctx->ctx);
+
+   /*
+    * ZKP(xb * s)
+    * XXX: this is kinda funky, because we're using
+    *
+    * g' = g^{xa + xc + xd}
+    *
+    * as the generator, which means X is g'^{xb * s}
+    * X = t1^{t2} = t1^{xb * s} = g^{(xa + xc + xd) * xb * s}
+    */
+    generate_step_part(send, t2, t1, ctx);
+
+   /* cleanup */
+    BN_free(t1);
+    BN_free(t2);
+
+    return 1;
+    }
+
+/* gx = g^{xc + xa + xb} * xd * s */
+static int compute_key(JPAKE_CTX *ctx, const BIGNUM *gx)
+    {
+    BIGNUM *t1 = BN_new();
+    BIGNUM *t2 = BN_new();
+    BIGNUM *t3 = BN_new();
+
+   /*
+    * K = (gx/g^{xb * xd * s})^{xb}
+    *   = (g^{(xc + xa + xb) * xd * s - xb * xd *s})^{xb}
+    *   = (g^{(xa + xc) * xd * s})^{xb}
+    *   = g^{(xa + xc) * xb * xd * s}
+    * [which is the same regardless of who calculates it]
+    */
+
+   /* t1 = (g^{xd})^{xb} = g^{xb * xd} */
+    BN_mod_exp(t1, ctx->p.gxd, ctx->xb, ctx->p.p, ctx->ctx);
+   /* t2 = -s = q-s */
+    BN_sub(t2, ctx->p.q, ctx->secret);
+   /* t3 = t1^t2 = g^{-xb * xd * s} */
+    BN_mod_exp(t3, t1, t2, ctx->p.p, ctx->ctx);
+   /* t1 = gx * t3 = X/g^{xb * xd * s} */
+    BN_mod_mul(t1, gx, t3, ctx->p.p, ctx->ctx);
+   /* K = t1^{xb} */
+    BN_mod_exp(ctx->key, t1, ctx->xb, ctx->p.p, ctx->ctx);
+
+   /* cleanup */
+    BN_free(t3);
+    BN_free(t2);
+    BN_free(t1);
+
+    return 1;
+    }
+
+int JPAKE_STEP2_process(JPAKE_CTX *ctx, const JPAKE_STEP2 *received)
+    {
+    BIGNUM *t1 = BN_new();
+    BIGNUM *t2 = BN_new();
+    int ret = 0;
+
+   /*
+    * g' = g^{xc + xa + xb} [from our POV]
+    * t1 = xa + xb
+    */
+    BN_mod_add(t1, ctx->xa, ctx->xb, ctx->p.q, ctx->ctx);
+   /* t2 = g^{t1} = g^{xa+xb} */
+    BN_mod_exp(t2, ctx->p.g, t1, ctx->p.p, ctx->ctx);
+   /* t1 = g^{xc} * t2 = g^{xc + xa + xb} */
+    BN_mod_mul(t1, ctx->p.gxc, t2, ctx->p.p, ctx->ctx);
+
+    if(verify_zkp(received, t1, ctx))
+	ret = 1;
+    else
+	JPAKEerr(JPAKE_F_JPAKE_STEP2_PROCESS, JPAKE_R_VERIFY_B_FAILED);
+
+    compute_key(ctx, received->gx);
+
+   /* cleanup */
+    BN_free(t2);
+    BN_free(t1);
+
+    return ret;
+    }
+
+static void quickhashbn(unsigned char *md, const BIGNUM *bn)
+    {
+    SHA_CTX sha;
+
+    SHA1_Init(&sha);
+    hashbn(&sha, bn);
+    SHA1_Final(md, &sha);
+    }
+
+void JPAKE_STEP3A_init(JPAKE_STEP3A *s3a)
+    {}
+
+int JPAKE_STEP3A_generate(JPAKE_STEP3A *send, JPAKE_CTX *ctx)
+    {
+    quickhashbn(send->hhk, ctx->key);
+    SHA1(send->hhk, sizeof send->hhk, send->hhk);
+
+    return 1;
+    }
+
+int JPAKE_STEP3A_process(JPAKE_CTX *ctx, const JPAKE_STEP3A *received)
+    {
+    unsigned char hhk[SHA_DIGEST_LENGTH];
+
+    quickhashbn(hhk, ctx->key);
+    SHA1(hhk, sizeof hhk, hhk);
+    if(memcmp(hhk, received->hhk, sizeof hhk))
+	{
+	JPAKEerr(JPAKE_F_JPAKE_STEP3A_PROCESS, JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH);
+	return 0;
+	}
+    return 1;
+    }
+
+void JPAKE_STEP3A_release(JPAKE_STEP3A *s3a)
+    {}
+
+void JPAKE_STEP3B_init(JPAKE_STEP3B *s3b)
+    {}
+
+int JPAKE_STEP3B_generate(JPAKE_STEP3B *send, JPAKE_CTX *ctx)
+    {
+    quickhashbn(send->hk, ctx->key);
+
+    return 1;
+    }
+
+int JPAKE_STEP3B_process(JPAKE_CTX *ctx, const JPAKE_STEP3B *received)
+    {
+    unsigned char hk[SHA_DIGEST_LENGTH];
+
+    quickhashbn(hk, ctx->key);
+    if(memcmp(hk, received->hk, sizeof hk))
+	{
+	JPAKEerr(JPAKE_F_JPAKE_STEP3B_PROCESS, JPAKE_R_HASH_OF_KEY_MISMATCH);
+	return 0;
+	}
+    return 1;
+    }
+
+void JPAKE_STEP3B_release(JPAKE_STEP3B *s3b)
+    {}
+
+const BIGNUM *JPAKE_get_shared_key(JPAKE_CTX *ctx)
+    {
+    return ctx->key;
+    }
+
diff --git a/crypto/jpake/jpake.h b/crypto/jpake/jpake.h
new file mode 100644
index 0000000..693ea18
--- /dev/null
+++ b/crypto/jpake/jpake.h
@@ -0,0 +1,129 @@
+/*
+ * Implement J-PAKE, as described in
+ * http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf
+ * 
+ * With hints from http://www.cl.cam.ac.uk/~fh240/software/JPAKE2.java.
+ */
+
+#ifndef HEADER_JPAKE_H
+#define HEADER_JPAKE_H
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_JPAKE
+#error JPAKE is disabled.
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <openssl/bn.h>
+#include <openssl/sha.h>
+
+typedef struct JPAKE_CTX JPAKE_CTX;
+
+/* Note that "g" in the ZKPs is not necessarily the J-PAKE g. */
+typedef struct
+    {
+    BIGNUM *gr; /* g^r (r random) */
+    BIGNUM *b;  /* b = r - x*h, h=hash(g, g^r, g^x, name) */
+    } JPAKE_ZKP;
+
+typedef struct
+    {
+    BIGNUM *gx;       /* g^x in step 1, g^(xa + xc + xd) * xb * s in step 2 */
+    JPAKE_ZKP zkpx;   /* ZKP(x) or ZKP(xb * s) */
+    } JPAKE_STEP_PART;
+
+typedef struct
+    {
+    JPAKE_STEP_PART p1;   /* g^x3, ZKP(x3) or g^x1, ZKP(x1) */
+    JPAKE_STEP_PART p2;   /* g^x4, ZKP(x4) or g^x2, ZKP(x2) */
+    } JPAKE_STEP1;
+
+typedef JPAKE_STEP_PART JPAKE_STEP2;
+
+typedef struct
+    {
+    unsigned char hhk[SHA_DIGEST_LENGTH];
+    } JPAKE_STEP3A;
+
+typedef struct
+    {
+    unsigned char hk[SHA_DIGEST_LENGTH];
+    } JPAKE_STEP3B;
+
+/* Parameters are copied */
+JPAKE_CTX *JPAKE_CTX_new(const char *name, const char *peer_name,
+			 const BIGNUM *p, const BIGNUM *g, const BIGNUM *q,
+			 const BIGNUM *secret);
+void JPAKE_CTX_free(JPAKE_CTX *ctx);
+
+/*
+ * Note that JPAKE_STEP1 can be used multiple times before release
+ * without another init.
+ */
+void JPAKE_STEP1_init(JPAKE_STEP1 *s1);
+int JPAKE_STEP1_generate(JPAKE_STEP1 *send, JPAKE_CTX *ctx);
+int JPAKE_STEP1_process(JPAKE_CTX *ctx, const JPAKE_STEP1 *received);
+void JPAKE_STEP1_release(JPAKE_STEP1 *s1);
+
+/*
+ * Note that JPAKE_STEP2 can be used multiple times before release
+ * without another init.
+ */
+void JPAKE_STEP2_init(JPAKE_STEP2 *s2);
+int JPAKE_STEP2_generate(JPAKE_STEP2 *send, JPAKE_CTX *ctx);
+int JPAKE_STEP2_process(JPAKE_CTX *ctx, const JPAKE_STEP2 *received);
+void JPAKE_STEP2_release(JPAKE_STEP2 *s2);
+
+/*
+ * Optionally verify the shared key. If the shared secrets do not
+ * match, the two ends will disagree about the shared key, but
+ * otherwise the protocol will succeed.
+ */
+void JPAKE_STEP3A_init(JPAKE_STEP3A *s3a);
+int JPAKE_STEP3A_generate(JPAKE_STEP3A *send, JPAKE_CTX *ctx);
+int JPAKE_STEP3A_process(JPAKE_CTX *ctx, const JPAKE_STEP3A *received);
+void JPAKE_STEP3A_release(JPAKE_STEP3A *s3a);
+
+void JPAKE_STEP3B_init(JPAKE_STEP3B *s3b);
+int JPAKE_STEP3B_generate(JPAKE_STEP3B *send, JPAKE_CTX *ctx);
+int JPAKE_STEP3B_process(JPAKE_CTX *ctx, const JPAKE_STEP3B *received);
+void JPAKE_STEP3B_release(JPAKE_STEP3B *s3b);
+
+/*
+ * the return value belongs to the library and will be released when
+ * ctx is released, and will change when a new handshake is performed.
+ */
+const BIGNUM *JPAKE_get_shared_key(JPAKE_CTX *ctx);
+
+/* 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_JPAKE_strings(void);
+
+/* Error codes for the JPAKE functions. */
+
+/* Function codes. */
+#define JPAKE_F_JPAKE_STEP1_PROCESS			 101
+#define JPAKE_F_JPAKE_STEP2_PROCESS			 102
+#define JPAKE_F_JPAKE_STEP3A_PROCESS			 103
+#define JPAKE_F_JPAKE_STEP3B_PROCESS			 104
+#define JPAKE_F_VERIFY_ZKP				 100
+
+/* Reason codes. */
+#define JPAKE_R_G_TO_THE_X4_IS_ONE			 105
+#define JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH		 106
+#define JPAKE_R_HASH_OF_KEY_MISMATCH			 107
+#define JPAKE_R_VERIFY_B_FAILED				 102
+#define JPAKE_R_VERIFY_X3_FAILED			 103
+#define JPAKE_R_VERIFY_X4_FAILED			 104
+#define JPAKE_R_ZKP_VERIFY_FAILED			 100
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/crypto/jpake/jpake_err.c b/crypto/jpake/jpake_err.c
new file mode 100644
index 0000000..1b95067
--- /dev/null
+++ b/crypto/jpake/jpake_err.c
@@ -0,0 +1,105 @@
+/* crypto/jpake/jpake_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-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
+ *    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/jpake.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+#define ERR_FUNC(func) ERR_PACK(ERR_LIB_JPAKE,func,0)
+#define ERR_REASON(reason) ERR_PACK(ERR_LIB_JPAKE,0,reason)
+
+static ERR_STRING_DATA JPAKE_str_functs[]=
+	{
+{ERR_FUNC(JPAKE_F_JPAKE_STEP1_PROCESS),	"JPAKE_STEP1_process"},
+{ERR_FUNC(JPAKE_F_JPAKE_STEP2_PROCESS),	"JPAKE_STEP2_process"},
+{ERR_FUNC(JPAKE_F_JPAKE_STEP3A_PROCESS),	"JPAKE_STEP3A_process"},
+{ERR_FUNC(JPAKE_F_JPAKE_STEP3B_PROCESS),	"JPAKE_STEP3B_process"},
+{ERR_FUNC(JPAKE_F_VERIFY_ZKP),	"VERIFY_ZKP"},
+{0,NULL}
+	};
+
+static ERR_STRING_DATA JPAKE_str_reasons[]=
+	{
+{ERR_REASON(JPAKE_R_G_TO_THE_X4_IS_ONE)  ,"g to the x4 is one"},
+{ERR_REASON(JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH),"hash of hash of key mismatch"},
+{ERR_REASON(JPAKE_R_HASH_OF_KEY_MISMATCH),"hash of key mismatch"},
+{ERR_REASON(JPAKE_R_VERIFY_B_FAILED)     ,"verify b failed"},
+{ERR_REASON(JPAKE_R_VERIFY_X3_FAILED)    ,"verify x3 failed"},
+{ERR_REASON(JPAKE_R_VERIFY_X4_FAILED)    ,"verify x4 failed"},
+{ERR_REASON(JPAKE_R_ZKP_VERIFY_FAILED)   ,"zkp verify failed"},
+{0,NULL}
+	};
+
+#endif
+
+void ERR_load_JPAKE_strings(void)
+	{
+#ifndef OPENSSL_NO_ERR
+
+	if (ERR_func_error_string(JPAKE_str_functs[0].error) == NULL)
+		{
+		ERR_load_strings(0,JPAKE_str_functs);
+		ERR_load_strings(0,JPAKE_str_reasons);
+		}
+#endif
+	}
diff --git a/crypto/jpake/jpaketest.c b/crypto/jpake/jpaketest.c
new file mode 100644
index 0000000..792fc49
--- /dev/null
+++ b/crypto/jpake/jpaketest.c
@@ -0,0 +1,192 @@
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_JPAKE
+
+#include <stdio.h>
+
+int main(int argc, char *argv[])
+{
+    printf("No J-PAKE support\n");
+    return(0);
+}
+
+#else
+
+#include <openssl/jpake.h>
+#include <openssl/err.h>
+
+static void showbn(const char *name, const BIGNUM *bn)
+    {
+    fputs(name, stdout);
+    fputs(" = ", stdout);
+    BN_print_fp(stdout, bn);
+    putc('\n', stdout);
+    }
+
+static int run_jpake(JPAKE_CTX *alice, JPAKE_CTX *bob)
+    {
+    JPAKE_STEP1 alice_s1;
+    JPAKE_STEP1 bob_s1;
+    JPAKE_STEP2 alice_s2;
+    JPAKE_STEP2 bob_s2;
+    JPAKE_STEP3A alice_s3a;
+    JPAKE_STEP3B bob_s3b;
+
+   /* Alice -> Bob: step 1 */
+    puts("A->B s1");
+    JPAKE_STEP1_init(&alice_s1);
+    JPAKE_STEP1_generate(&alice_s1, alice);
+    if(!JPAKE_STEP1_process(bob, &alice_s1))
+	{
+	printf("Bob fails to process Alice's step 1\n");
+	ERR_print_errors_fp(stdout);
+	return 1;
+	}
+    JPAKE_STEP1_release(&alice_s1);
+
+   /* Bob -> Alice: step 1 */
+    puts("B->A s1");
+    JPAKE_STEP1_init(&bob_s1);
+    JPAKE_STEP1_generate(&bob_s1, bob);
+    if(!JPAKE_STEP1_process(alice, &bob_s1))
+	{
+	printf("Alice fails to process Bob's step 1\n");
+	ERR_print_errors_fp(stdout);
+	return 2;
+	}
+    JPAKE_STEP1_release(&bob_s1);
+
+   /* Alice -> Bob: step 2 */
+    puts("A->B s2");
+    JPAKE_STEP2_init(&alice_s2);
+    JPAKE_STEP2_generate(&alice_s2, alice);
+    if(!JPAKE_STEP2_process(bob, &alice_s2))
+	{
+	printf("Bob fails to process Alice's step 2\n");
+	ERR_print_errors_fp(stdout);
+	return 3;
+	}
+    JPAKE_STEP2_release(&alice_s2);
+
+   /* Bob -> Alice: step 2 */
+    puts("B->A s2");
+    JPAKE_STEP2_init(&bob_s2);
+    JPAKE_STEP2_generate(&bob_s2, bob);
+    if(!JPAKE_STEP2_process(alice, &bob_s2))
+	{
+	printf("Alice fails to process Bob's step 2\n");
+	ERR_print_errors_fp(stdout);
+	return 4;
+	}
+    JPAKE_STEP2_release(&bob_s2);
+
+    showbn("Alice's key", JPAKE_get_shared_key(alice));
+    showbn("Bob's key  ", JPAKE_get_shared_key(bob));
+
+   /* Alice -> Bob: step 3a */
+    puts("A->B s3a");
+    JPAKE_STEP3A_init(&alice_s3a);
+    JPAKE_STEP3A_generate(&alice_s3a, alice);
+    if(!JPAKE_STEP3A_process(bob, &alice_s3a))
+	{
+	printf("Bob fails to process Alice's step 3a\n");
+	ERR_print_errors_fp(stdout);
+	return 5;
+	}
+    JPAKE_STEP3A_release(&alice_s3a);
+    
+   /* Bob -> Alice: step 3b */
+    puts("B->A s3b");
+    JPAKE_STEP3B_init(&bob_s3b);
+    JPAKE_STEP3B_generate(&bob_s3b, bob);
+    if(!JPAKE_STEP3B_process(alice, &bob_s3b))
+	{
+	printf("Alice fails to process Bob's step 3b\n");
+	ERR_print_errors_fp(stdout);
+	return 6;
+	}
+    JPAKE_STEP3B_release(&bob_s3b);
+
+    return 0;
+    }
+
+int main(int argc, char **argv)
+    {
+    JPAKE_CTX *alice;
+    JPAKE_CTX *bob;
+    BIGNUM *p = NULL;
+    BIGNUM *g = NULL;
+    BIGNUM *q = NULL;
+    BIGNUM *secret = BN_new();
+    BIO *bio_err;
+
+    bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+    CRYPTO_malloc_debug_init();
+    CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
+    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+
+    ERR_load_crypto_strings();
+
+    /*
+    BN_hex2bn(&p, "fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7");
+    BN_hex2bn(&g, "f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a");
+    BN_hex2bn(&q, "9760508f15230bccb292b982a2eb840bf0581cf5");
+    */
+    /*
+    p = BN_new();
+    BN_generate_prime(p, 1024, 1, NULL, NULL, NULL, NULL);
+    */
+   /* Use a safe prime for p (that we found earlier) */
+    BN_hex2bn(&p, "F9E5B365665EA7A05A9C534502780FEE6F1AB5BD4F49947FD036DBD7E905269AF46EF28B0FC07487EE4F5D20FB3C0AF8E700F3A2FA3414970CBED44FEDFF80CE78D800F184BB82435D137AADA2C6C16523247930A63B85661D1FC817A51ACD96168E95898A1F83A79FFB529368AA7833ABD1B0C3AEDDB14D2E1A2F71D99F763F");
+    showbn("p", p);
+    g = BN_new();
+    BN_set_word(g, 2);
+    showbn("g", g);
+    q = BN_new();
+    BN_rshift1(q, p);
+    showbn("q", q);
+
+    BN_rand(secret, 32, -1, 0);
+
+   /* A normal run, expect this to work... */
+    alice = JPAKE_CTX_new("Alice", "Bob", p, g, q, secret);
+    bob = JPAKE_CTX_new("Bob", "Alice", p, g, q, secret);
+
+    if(run_jpake(alice, bob) != 0)
+	{
+	fprintf(stderr, "Plain JPAKE run failed\n");
+	return 1;
+	}
+
+    JPAKE_CTX_free(bob);
+    JPAKE_CTX_free(alice);
+
+   /* Now give Alice and Bob different secrets */
+    alice = JPAKE_CTX_new("Alice", "Bob", p, g, q, secret);
+    BN_add_word(secret, 1);
+    bob = JPAKE_CTX_new("Bob", "Alice", p, g, q, secret);
+
+    if(run_jpake(alice, bob) != 5)
+	{
+	fprintf(stderr, "Mismatched secret JPAKE run failed\n");
+	return 1;
+	}
+
+    JPAKE_CTX_free(bob);
+    JPAKE_CTX_free(alice);
+
+    BN_free(secret);
+    BN_free(q);
+    BN_free(g);
+    BN_free(p);
+
+    CRYPTO_cleanup_all_ex_data();
+    ERR_remove_state(0);
+    ERR_free_strings();
+    CRYPTO_mem_leaks(bio_err);
+
+    return 0;
+    }
+
+#endif
diff --git a/crypto/krb5/Makefile b/crypto/krb5/Makefile
index 1407739..8efb9e8 100644
--- a/crypto/krb5/Makefile
+++ b/crypto/krb5/Makefile
@@ -34,7 +34,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
diff --git a/crypto/lhash/Makefile b/crypto/lhash/Makefile
index 82bddac..35f0932 100644
--- a/crypto/lhash/Makefile
+++ b/crypto/lhash/Makefile
@@ -33,7 +33,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
diff --git a/crypto/md32_common.h b/crypto/md32_common.h
index 089c450..61bcd97 100644
--- a/crypto/md32_common.h
+++ b/crypto/md32_common.h
@@ -301,7 +301,7 @@
 		{
 		p=(unsigned char *)c->data;
 
-		if ((n+len) >= HASH_CBLOCK)
+		if (len >= HASH_CBLOCK || len+n >= HASH_CBLOCK)
 			{
 			memcpy (p+n,data,HASH_CBLOCK-n);
 			HASH_BLOCK_DATA_ORDER (c,p,1);
diff --git a/crypto/md4/Makefile b/crypto/md4/Makefile
index ef97bb0..0bc4896 100644
--- a/crypto/md4/Makefile
+++ b/crypto/md4/Makefile
@@ -34,7 +34,7 @@
 all:    lib
 
 lib:    $(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -75,9 +75,13 @@
 
 # DO NOT DELETE THIS LINE -- make depend depends on it.
 
-md4_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/md4.h
-md4_dgst.o: ../../include/openssl/opensslconf.h
-md4_dgst.o: ../../include/openssl/opensslv.h ../md32_common.h md4_dgst.c
+md4_dgst.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+md4_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+md4_dgst.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+md4_dgst.o: ../../include/openssl/md4.h ../../include/openssl/opensslconf.h
+md4_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+md4_dgst.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+md4_dgst.o: ../../include/openssl/symhacks.h ../md32_common.h md4_dgst.c
 md4_dgst.o: md4_locl.h
 md4_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 md4_one.o: ../../include/openssl/md4.h ../../include/openssl/opensslconf.h
diff --git a/crypto/md4/md4.h b/crypto/md4/md4.h
index 5598c93..ba1fe4a 100644
--- a/crypto/md4/md4.h
+++ b/crypto/md4/md4.h
@@ -105,6 +105,9 @@
 	unsigned int num;
 	} MD4_CTX;
 
+#ifdef OPENSSL_FIPS
+int private_MD4_Init(MD4_CTX *c);
+#endif
 int MD4_Init(MD4_CTX *c);
 int MD4_Update(MD4_CTX *c, const void *data, size_t len);
 int MD4_Final(unsigned char *md, MD4_CTX *c);
diff --git a/crypto/md4/md4_dgst.c b/crypto/md4/md4_dgst.c
index cfef94a..0f54486 100644
--- a/crypto/md4/md4_dgst.c
+++ b/crypto/md4/md4_dgst.c
@@ -59,6 +59,11 @@
 #include <stdio.h>
 #include "md4_locl.h"
 #include <openssl/opensslv.h>
+#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 
 const char MD4_version[]="MD4" OPENSSL_VERSION_PTEXT;
 
@@ -70,7 +75,7 @@
 #define INIT_DATA_C (unsigned long)0x98badcfeL
 #define INIT_DATA_D (unsigned long)0x10325476L
 
-int MD4_Init(MD4_CTX *c)
+FIPS_NON_FIPS_MD_Init(MD4)
 	{
 	c->A=INIT_DATA_A;
 	c->B=INIT_DATA_B;
diff --git a/crypto/md5/Makefile b/crypto/md5/Makefile
index ceb00e8..3c450fc 100644
--- a/crypto/md5/Makefile
+++ b/crypto/md5/Makefile
@@ -38,7 +38,7 @@
 all:    lib
 
 lib:    $(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -91,9 +91,13 @@
 
 # DO NOT DELETE THIS LINE -- make depend depends on it.
 
-md5_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/md5.h
-md5_dgst.o: ../../include/openssl/opensslconf.h
-md5_dgst.o: ../../include/openssl/opensslv.h ../md32_common.h md5_dgst.c
+md5_dgst.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+md5_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+md5_dgst.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+md5_dgst.o: ../../include/openssl/md5.h ../../include/openssl/opensslconf.h
+md5_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+md5_dgst.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+md5_dgst.o: ../../include/openssl/symhacks.h ../md32_common.h md5_dgst.c
 md5_dgst.o: md5_locl.h
 md5_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 md5_one.o: ../../include/openssl/md5.h ../../include/openssl/opensslconf.h
diff --git a/crypto/md5/md5.h b/crypto/md5/md5.h
index dbdc0e1..0761f84 100644
--- a/crypto/md5/md5.h
+++ b/crypto/md5/md5.h
@@ -105,6 +105,9 @@
 	unsigned int num;
 	} MD5_CTX;
 
+#ifdef OPENSSL_FIPS
+int private_MD5_Init(MD5_CTX *c);
+#endif
 int MD5_Init(MD5_CTX *c);
 int MD5_Update(MD5_CTX *c, const void *data, size_t len);
 int MD5_Final(unsigned char *md, MD5_CTX *c);
diff --git a/crypto/md5/md5_dgst.c b/crypto/md5/md5_dgst.c
index b96e332..47bb902 100644
--- a/crypto/md5/md5_dgst.c
+++ b/crypto/md5/md5_dgst.c
@@ -59,6 +59,11 @@
 #include <stdio.h>
 #include "md5_locl.h"
 #include <openssl/opensslv.h>
+#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 
 const char MD5_version[]="MD5" OPENSSL_VERSION_PTEXT;
 
@@ -70,7 +75,7 @@
 #define INIT_DATA_C (unsigned long)0x98badcfeL
 #define INIT_DATA_D (unsigned long)0x10325476L
 
-int MD5_Init(MD5_CTX *c)
+FIPS_NON_FIPS_MD_Init(MD5)
 	{
 	c->A=INIT_DATA_A;
 	c->B=INIT_DATA_B;
diff --git a/crypto/mdc2/Makefile b/crypto/mdc2/Makefile
index 1d064f1..ea25688 100644
--- a/crypto/mdc2/Makefile
+++ b/crypto/mdc2/Makefile
@@ -33,7 +33,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
diff --git a/crypto/mdc2/mdc2.h b/crypto/mdc2/mdc2.h
index 72778a5..7e13541 100644
--- a/crypto/mdc2/mdc2.h
+++ b/crypto/mdc2/mdc2.h
@@ -80,7 +80,9 @@
 	int pad_type; /* either 1 or 2, default 1 */
 	} MDC2_CTX;
 
-
+#ifdef OPENSSL_FIPS
+int private_MDC2_Init(MDC2_CTX *c);
+#endif
 int MDC2_Init(MDC2_CTX *c);
 int MDC2_Update(MDC2_CTX *c, const unsigned char *data, size_t len);
 int MDC2_Final(unsigned char *md, MDC2_CTX *c);
diff --git a/crypto/mdc2/mdc2dgst.c b/crypto/mdc2/mdc2dgst.c
index 4aa406e..a36b3f5 100644
--- a/crypto/mdc2/mdc2dgst.c
+++ b/crypto/mdc2/mdc2dgst.c
@@ -61,6 +61,11 @@
 #include <string.h>
 #include <openssl/des.h>
 #include <openssl/mdc2.h>
+#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 
 #undef c2l
 #define c2l(c,l)	(l =((DES_LONG)(*((c)++)))    , \
@@ -75,7 +80,7 @@
 			*((c)++)=(unsigned char)(((l)>>24L)&0xff))
 
 static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len);
-int MDC2_Init(MDC2_CTX *c)
+FIPS_NON_FIPS_MD_Init(MDC2)
 	{
 	c->num=0;
 	c->pad_type=1;
diff --git a/crypto/mem.c b/crypto/mem.c
index 6635167..00ebaf0 100644
--- a/crypto/mem.c
+++ b/crypto/mem.c
@@ -101,7 +101,7 @@
 
 /* may be changed as long as 'allow_customize_debug' is set */
 /* XXX use correct function pointer types */
-#ifdef CRYPTO_MDEBUG
+#if defined(CRYPTO_MDEBUG) && !defined(OPENSSL_FIPS)
 /* use default functions from mem_dbg.c */
 static void (*malloc_debug_func)(void *,int,const char *,int,int)
 	= CRYPTO_dbg_malloc;
@@ -110,6 +110,14 @@
 static void (*free_debug_func)(void *,int) = CRYPTO_dbg_free;
 static void (*set_debug_options_func)(long) = CRYPTO_dbg_set_options;
 static long (*get_debug_options_func)(void) = CRYPTO_dbg_get_options;
+
+static int  (*push_info_func)(const char *info, const char *file, int line)
+	= CRYPTO_dbg_push_info;
+static int  (*pop_info_func)(void)
+	= CRYPTO_dbg_pop_info;
+static int (*remove_all_info_func)(void)
+	= CRYPTO_dbg_remove_all_info;
+
 #else
 /* applications can use CRYPTO_malloc_debug_init() to select above case
  * at run-time */
@@ -119,6 +127,13 @@
 static void (*free_debug_func)(void *,int) = NULL;
 static void (*set_debug_options_func)(long) = NULL;
 static long (*get_debug_options_func)(void) = NULL;
+
+
+static int  (*push_info_func)(const char *info, const char *file, int line)
+	= NULL;
+static int  (*pop_info_func)(void) = NULL;
+static int (*remove_all_info_func)(void) = NULL;
+
 #endif
 
 
@@ -194,6 +209,15 @@
 	return 1;
 	}
 
+void CRYPTO_set_mem_info_functions(
+	int  (*push_info_fn)(const char *info, const char *file, int line),
+	int  (*pop_info_fn)(void),
+	int (*remove_all_info_fn)(void))
+	{
+	push_info_func = push_info_fn;
+	pop_info_func = pop_info_fn;
+	remove_all_info_func = remove_all_info_fn;
+	}
 
 void CRYPTO_get_mem_functions(void *(**m)(size_t), void *(**r)(void *, size_t),
 	void (**f)(void *))
@@ -399,3 +423,24 @@
 		return get_debug_options_func();
 	return 0;
 	}
+
+int CRYPTO_push_info_(const char *info, const char *file, int line)
+	{
+	if (push_info_func)
+		return push_info_func(info, file, line);
+	return 1;
+	}
+
+int CRYPTO_pop_info(void)
+	{
+	if (pop_info_func)
+		return pop_info_func();
+	return 1;
+	}
+
+int CRYPTO_remove_all_info(void)
+	{
+	if (remove_all_info_func)
+		return remove_all_info_func();
+	return 1;
+	}
diff --git a/crypto/mem_dbg.c b/crypto/mem_dbg.c
index 8316485..dfeb084 100644
--- a/crypto/mem_dbg.c
+++ b/crypto/mem_dbg.c
@@ -330,7 +330,7 @@
 	return(ret);
 	}
 
-int CRYPTO_push_info_(const char *info, const char *file, int line)
+int CRYPTO_dbg_push_info(const char *info, const char *file, int line)
 	{
 	APP_INFO *ami, *amim;
 	int ret=0;
@@ -380,7 +380,7 @@
 	return(ret);
 	}
 
-int CRYPTO_pop_info(void)
+int CRYPTO_dbg_pop_info(void)
 	{
 	int ret=0;
 
@@ -395,7 +395,7 @@
 	return(ret);
 	}
 
-int CRYPTO_remove_all_info(void)
+int CRYPTO_dbg_remove_all_info(void)
 	{
 	int ret=0;
 
@@ -793,3 +793,25 @@
 	lh_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), &cb);
 	CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
 	}
+
+void CRYPTO_malloc_debug_init(void)
+	{
+	CRYPTO_set_mem_debug_functions(
+		CRYPTO_dbg_malloc,
+		CRYPTO_dbg_realloc,
+		CRYPTO_dbg_free,
+		CRYPTO_dbg_set_options,
+		CRYPTO_dbg_get_options);
+	CRYPTO_set_mem_info_functions(
+		CRYPTO_dbg_push_info,
+		CRYPTO_dbg_pop_info,
+		CRYPTO_dbg_remove_all_info);
+	}
+
+char *CRYPTO_strdup(const char *str, const char *file, int line)
+	{
+	char *ret = CRYPTO_malloc(strlen(str)+1, file, line);
+
+	strcpy(ret, str);
+	return ret;
+	}
diff --git a/crypto/o_init.c b/crypto/o_init.c
new file mode 100644
index 0000000..00ed65a
--- /dev/null
+++ b/crypto/o_init.c
@@ -0,0 +1,86 @@
+/* o_init.c */
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2007 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).
+ *
+ */
+
+#include <e_os.h>
+#include <openssl/err.h>
+
+/* Perform any essential OpenSSL initialization operations.
+ * Currently only sets FIPS callbacks
+ */
+
+void OPENSSL_init(void)
+	{
+#ifdef OPENSSL_FIPS
+	static int done = 0;
+	if (!done)
+		{
+		int_ERR_lib_init();
+#ifdef CRYPTO_MDEBUG
+		CRYPTO_malloc_debug_init();
+#endif
+#ifdef OPENSSL_ENGINE
+		int_EVP_MD_init_engine_callbacks();
+		int_EVP_CIPHER_init_engine_callbacks();
+		int_RAND_init_engine_callbacks();
+#endif
+		done = 1;
+		}
+#endif
+	}
+		
+
diff --git a/crypto/objects/Makefile b/crypto/objects/Makefile
index 9c56150..25e8b23 100644
--- a/crypto/objects/Makefile
+++ b/crypto/objects/Makefile
@@ -34,7 +34,7 @@
 all:	obj_dat.h lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h
index 99acf13..dccc15e 100644
--- a/crypto/objects/obj_dat.h
+++ b/crypto/objects/obj_dat.h
@@ -62,12 +62,12 @@
  * [including the GNU Public Licence.]
  */
 
-#define NUM_NID 791
-#define NUM_SN 784
-#define NUM_LN 784
-#define NUM_OBJ 740
+#define NUM_NID 859
+#define NUM_SN 852
+#define NUM_LN 852
+#define NUM_OBJ 806
 
-static unsigned char lvalues[5258]={
+static unsigned char lvalues[5722]={
 0x00,                                        /* [  0] OBJ_undef */
 0x2A,0x86,0x48,0x86,0xF7,0x0D,               /* [  1] OBJ_rsadsi */
 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,          /* [  7] OBJ_pkcs */
@@ -808,6 +808,72 @@
 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x05,/* [5230] OBJ_id_aes128_wrap */
 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x19,/* [5239] OBJ_id_aes192_wrap */
 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2D,/* [5248] OBJ_id_aes256_wrap */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x02,          /* [5257] OBJ_ecdsa_with_Recommended */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,          /* [5264] OBJ_ecdsa_with_Specified */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x01,     /* [5271] OBJ_ecdsa_with_SHA224 */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,     /* [5279] OBJ_ecdsa_with_SHA256 */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,     /* [5287] OBJ_ecdsa_with_SHA384 */
+0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04,     /* [5295] OBJ_ecdsa_with_SHA512 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x06,     /* [5303] OBJ_hmacWithMD5 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x08,     /* [5311] OBJ_hmacWithSHA224 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x09,     /* [5319] OBJ_hmacWithSHA256 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0A,     /* [5327] OBJ_hmacWithSHA384 */
+0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0B,     /* [5335] OBJ_hmacWithSHA512 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x01,/* [5343] OBJ_dsa_with_SHA224 */
+0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x02,/* [5352] OBJ_dsa_with_SHA256 */
+0x28,0xCF,0x06,0x03,0x00,0x37,               /* [5361] OBJ_whirlpool */
+0x2A,0x85,0x03,0x02,0x02,                    /* [5367] OBJ_cryptopro */
+0x2A,0x85,0x03,0x02,0x09,                    /* [5372] OBJ_cryptocom */
+0x2A,0x85,0x03,0x02,0x02,0x03,               /* [5377] OBJ_id_GostR3411_94_with_GostR3410_2001 */
+0x2A,0x85,0x03,0x02,0x02,0x04,               /* [5383] OBJ_id_GostR3411_94_with_GostR3410_94 */
+0x2A,0x85,0x03,0x02,0x02,0x09,               /* [5389] OBJ_id_GostR3411_94 */
+0x2A,0x85,0x03,0x02,0x02,0x0A,               /* [5395] OBJ_id_HMACGostR3411_94 */
+0x2A,0x85,0x03,0x02,0x02,0x13,               /* [5401] OBJ_id_GostR3410_2001 */
+0x2A,0x85,0x03,0x02,0x02,0x14,               /* [5407] OBJ_id_GostR3410_94 */
+0x2A,0x85,0x03,0x02,0x02,0x15,               /* [5413] OBJ_id_Gost28147_89 */
+0x2A,0x85,0x03,0x02,0x02,0x16,               /* [5419] OBJ_id_Gost28147_89_MAC */
+0x2A,0x85,0x03,0x02,0x02,0x17,               /* [5425] OBJ_id_GostR3411_94_prf */
+0x2A,0x85,0x03,0x02,0x02,0x62,               /* [5431] OBJ_id_GostR3410_2001DH */
+0x2A,0x85,0x03,0x02,0x02,0x63,               /* [5437] OBJ_id_GostR3410_94DH */
+0x2A,0x85,0x03,0x02,0x02,0x0E,0x01,          /* [5443] OBJ_id_Gost28147_89_CryptoPro_KeyMeshing */
+0x2A,0x85,0x03,0x02,0x02,0x0E,0x00,          /* [5450] OBJ_id_Gost28147_89_None_KeyMeshing */
+0x2A,0x85,0x03,0x02,0x02,0x1E,0x00,          /* [5457] OBJ_id_GostR3411_94_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1E,0x01,          /* [5464] OBJ_id_GostR3411_94_CryptoProParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x00,          /* [5471] OBJ_id_Gost28147_89_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x01,          /* [5478] OBJ_id_Gost28147_89_CryptoPro_A_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x02,          /* [5485] OBJ_id_Gost28147_89_CryptoPro_B_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x03,          /* [5492] OBJ_id_Gost28147_89_CryptoPro_C_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x04,          /* [5499] OBJ_id_Gost28147_89_CryptoPro_D_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x05,          /* [5506] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x06,          /* [5513] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x1F,0x07,          /* [5520] OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x00,          /* [5527] OBJ_id_GostR3410_94_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x02,          /* [5534] OBJ_id_GostR3410_94_CryptoPro_A_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x03,          /* [5541] OBJ_id_GostR3410_94_CryptoPro_B_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x04,          /* [5548] OBJ_id_GostR3410_94_CryptoPro_C_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x20,0x05,          /* [5555] OBJ_id_GostR3410_94_CryptoPro_D_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x21,0x01,          /* [5562] OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x21,0x02,          /* [5569] OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x21,0x03,          /* [5576] OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x00,          /* [5583] OBJ_id_GostR3410_2001_TestParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x01,          /* [5590] OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x02,          /* [5597] OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x23,0x03,          /* [5604] OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x24,0x00,          /* [5611] OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x24,0x01,          /* [5618] OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x01,          /* [5625] OBJ_id_GostR3410_94_a */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x02,          /* [5632] OBJ_id_GostR3410_94_aBis */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x03,          /* [5639] OBJ_id_GostR3410_94_b */
+0x2A,0x85,0x03,0x02,0x02,0x14,0x04,          /* [5646] OBJ_id_GostR3410_94_bBis */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x06,0x01,     /* [5653] OBJ_id_Gost28147_89_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x03,     /* [5661] OBJ_id_GostR3410_94_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x04,     /* [5669] OBJ_id_GostR3410_2001_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x03,     /* [5677] OBJ_id_GostR3411_94_with_GostR3410_94_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x04,     /* [5685] OBJ_id_GostR3411_94_with_GostR3410_2001_cc */
+0x2A,0x85,0x03,0x02,0x09,0x01,0x08,0x01,     /* [5693] OBJ_id_GostR3410_2001_ParamSet_cc */
+0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x02,/* [5701] OBJ_LocalKeySet */
+0x55,0x1D,0x2E,                              /* [5710] OBJ_freshest_crl */
+0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x03,     /* [5713] OBJ_id_on_permanentIdentifier */
 };
 
 static ASN1_OBJECT nid_objs[NUM_NID]={
@@ -2039,6 +2105,163 @@
 	&(lvalues[5239]),0},
 {"id-aes256-wrap","id-aes256-wrap",NID_id_aes256_wrap,9,
 	&(lvalues[5248]),0},
+{"ecdsa-with-Recommended","ecdsa-with-Recommended",
+	NID_ecdsa_with_Recommended,7,&(lvalues[5257]),0},
+{"ecdsa-with-Specified","ecdsa-with-Specified",
+	NID_ecdsa_with_Specified,7,&(lvalues[5264]),0},
+{"ecdsa-with-SHA224","ecdsa-with-SHA224",NID_ecdsa_with_SHA224,8,
+	&(lvalues[5271]),0},
+{"ecdsa-with-SHA256","ecdsa-with-SHA256",NID_ecdsa_with_SHA256,8,
+	&(lvalues[5279]),0},
+{"ecdsa-with-SHA384","ecdsa-with-SHA384",NID_ecdsa_with_SHA384,8,
+	&(lvalues[5287]),0},
+{"ecdsa-with-SHA512","ecdsa-with-SHA512",NID_ecdsa_with_SHA512,8,
+	&(lvalues[5295]),0},
+{"hmacWithMD5","hmacWithMD5",NID_hmacWithMD5,8,&(lvalues[5303]),0},
+{"hmacWithSHA224","hmacWithSHA224",NID_hmacWithSHA224,8,
+	&(lvalues[5311]),0},
+{"hmacWithSHA256","hmacWithSHA256",NID_hmacWithSHA256,8,
+	&(lvalues[5319]),0},
+{"hmacWithSHA384","hmacWithSHA384",NID_hmacWithSHA384,8,
+	&(lvalues[5327]),0},
+{"hmacWithSHA512","hmacWithSHA512",NID_hmacWithSHA512,8,
+	&(lvalues[5335]),0},
+{"dsa_with_SHA224","dsa_with_SHA224",NID_dsa_with_SHA224,9,
+	&(lvalues[5343]),0},
+{"dsa_with_SHA256","dsa_with_SHA256",NID_dsa_with_SHA256,9,
+	&(lvalues[5352]),0},
+{"whirlpool","whirlpool",NID_whirlpool,6,&(lvalues[5361]),0},
+{"cryptopro","cryptopro",NID_cryptopro,5,&(lvalues[5367]),0},
+{"cryptocom","cryptocom",NID_cryptocom,5,&(lvalues[5372]),0},
+{"id-GostR3411-94-with-GostR3410-2001",
+	"GOST R 34.11-94 with GOST R 34.10-2001",
+	NID_id_GostR3411_94_with_GostR3410_2001,6,&(lvalues[5377]),0},
+{"id-GostR3411-94-with-GostR3410-94",
+	"GOST R 34.11-94 with GOST R 34.10-94",
+	NID_id_GostR3411_94_with_GostR3410_94,6,&(lvalues[5383]),0},
+{"md_gost94","GOST R 34.11-94",NID_id_GostR3411_94,6,&(lvalues[5389]),0},
+{"id-HMACGostR3411-94","HMAC GOST 34.11-94",NID_id_HMACGostR3411_94,6,
+	&(lvalues[5395]),0},
+{"gost2001","GOST R 34.10-2001",NID_id_GostR3410_2001,6,
+	&(lvalues[5401]),0},
+{"gost94","GOST R 34.10-94",NID_id_GostR3410_94,6,&(lvalues[5407]),0},
+{"gost89","GOST 28147-89",NID_id_Gost28147_89,6,&(lvalues[5413]),0},
+{"gost89-cnt","gost89-cnt",NID_gost89_cnt,0,NULL,0},
+{"gost-mac","GOST 28147-89 MAC",NID_id_Gost28147_89_MAC,6,
+	&(lvalues[5419]),0},
+{"prf-gostr3411-94","GOST R 34.11-94 PRF",NID_id_GostR3411_94_prf,6,
+	&(lvalues[5425]),0},
+{"id-GostR3410-2001DH","GOST R 34.10-2001 DH",NID_id_GostR3410_2001DH,
+	6,&(lvalues[5431]),0},
+{"id-GostR3410-94DH","GOST R 34.10-94 DH",NID_id_GostR3410_94DH,6,
+	&(lvalues[5437]),0},
+{"id-Gost28147-89-CryptoPro-KeyMeshing",
+	"id-Gost28147-89-CryptoPro-KeyMeshing",
+	NID_id_Gost28147_89_CryptoPro_KeyMeshing,7,&(lvalues[5443]),0},
+{"id-Gost28147-89-None-KeyMeshing","id-Gost28147-89-None-KeyMeshing",
+	NID_id_Gost28147_89_None_KeyMeshing,7,&(lvalues[5450]),0},
+{"id-GostR3411-94-TestParamSet","id-GostR3411-94-TestParamSet",
+	NID_id_GostR3411_94_TestParamSet,7,&(lvalues[5457]),0},
+{"id-GostR3411-94-CryptoProParamSet",
+	"id-GostR3411-94-CryptoProParamSet",
+	NID_id_GostR3411_94_CryptoProParamSet,7,&(lvalues[5464]),0},
+{"id-Gost28147-89-TestParamSet","id-Gost28147-89-TestParamSet",
+	NID_id_Gost28147_89_TestParamSet,7,&(lvalues[5471]),0},
+{"id-Gost28147-89-CryptoPro-A-ParamSet",
+	"id-Gost28147-89-CryptoPro-A-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_A_ParamSet,7,&(lvalues[5478]),0},
+{"id-Gost28147-89-CryptoPro-B-ParamSet",
+	"id-Gost28147-89-CryptoPro-B-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_B_ParamSet,7,&(lvalues[5485]),0},
+{"id-Gost28147-89-CryptoPro-C-ParamSet",
+	"id-Gost28147-89-CryptoPro-C-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_C_ParamSet,7,&(lvalues[5492]),0},
+{"id-Gost28147-89-CryptoPro-D-ParamSet",
+	"id-Gost28147-89-CryptoPro-D-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_D_ParamSet,7,&(lvalues[5499]),0},
+{"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet",
+	"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet,7,&(lvalues[5506]),
+	0},
+{"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet",
+	"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet,7,&(lvalues[5513]),
+	0},
+{"id-Gost28147-89-CryptoPro-RIC-1-ParamSet",
+	"id-Gost28147-89-CryptoPro-RIC-1-ParamSet",
+	NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet,7,&(lvalues[5520]),0},
+{"id-GostR3410-94-TestParamSet","id-GostR3410-94-TestParamSet",
+	NID_id_GostR3410_94_TestParamSet,7,&(lvalues[5527]),0},
+{"id-GostR3410-94-CryptoPro-A-ParamSet",
+	"id-GostR3410-94-CryptoPro-A-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_A_ParamSet,7,&(lvalues[5534]),0},
+{"id-GostR3410-94-CryptoPro-B-ParamSet",
+	"id-GostR3410-94-CryptoPro-B-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_B_ParamSet,7,&(lvalues[5541]),0},
+{"id-GostR3410-94-CryptoPro-C-ParamSet",
+	"id-GostR3410-94-CryptoPro-C-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_C_ParamSet,7,&(lvalues[5548]),0},
+{"id-GostR3410-94-CryptoPro-D-ParamSet",
+	"id-GostR3410-94-CryptoPro-D-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_D_ParamSet,7,&(lvalues[5555]),0},
+{"id-GostR3410-94-CryptoPro-XchA-ParamSet",
+	"id-GostR3410-94-CryptoPro-XchA-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_XchA_ParamSet,7,&(lvalues[5562]),0},
+{"id-GostR3410-94-CryptoPro-XchB-ParamSet",
+	"id-GostR3410-94-CryptoPro-XchB-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_XchB_ParamSet,7,&(lvalues[5569]),0},
+{"id-GostR3410-94-CryptoPro-XchC-ParamSet",
+	"id-GostR3410-94-CryptoPro-XchC-ParamSet",
+	NID_id_GostR3410_94_CryptoPro_XchC_ParamSet,7,&(lvalues[5576]),0},
+{"id-GostR3410-2001-TestParamSet","id-GostR3410-2001-TestParamSet",
+	NID_id_GostR3410_2001_TestParamSet,7,&(lvalues[5583]),0},
+{"id-GostR3410-2001-CryptoPro-A-ParamSet",
+	"id-GostR3410-2001-CryptoPro-A-ParamSet",
+	NID_id_GostR3410_2001_CryptoPro_A_ParamSet,7,&(lvalues[5590]),0},
+{"id-GostR3410-2001-CryptoPro-B-ParamSet",
+	"id-GostR3410-2001-CryptoPro-B-ParamSet",
+	NID_id_GostR3410_2001_CryptoPro_B_ParamSet,7,&(lvalues[5597]),0},
+{"id-GostR3410-2001-CryptoPro-C-ParamSet",
+	"id-GostR3410-2001-CryptoPro-C-ParamSet",
+	NID_id_GostR3410_2001_CryptoPro_C_ParamSet,7,&(lvalues[5604]),0},
+{"id-GostR3410-2001-CryptoPro-XchA-ParamSet",
+	"id-GostR3410-2001-CryptoPro-XchA-ParamSet",
+	NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet,7,&(lvalues[5611]),0},
+	
+{"id-GostR3410-2001-CryptoPro-XchB-ParamSet",
+	"id-GostR3410-2001-CryptoPro-XchB-ParamSet",
+	NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet,7,&(lvalues[5618]),0},
+	
+{"id-GostR3410-94-a","id-GostR3410-94-a",NID_id_GostR3410_94_a,7,
+	&(lvalues[5625]),0},
+{"id-GostR3410-94-aBis","id-GostR3410-94-aBis",
+	NID_id_GostR3410_94_aBis,7,&(lvalues[5632]),0},
+{"id-GostR3410-94-b","id-GostR3410-94-b",NID_id_GostR3410_94_b,7,
+	&(lvalues[5639]),0},
+{"id-GostR3410-94-bBis","id-GostR3410-94-bBis",
+	NID_id_GostR3410_94_bBis,7,&(lvalues[5646]),0},
+{"id-Gost28147-89-cc","GOST 28147-89 Cryptocom ParamSet",
+	NID_id_Gost28147_89_cc,8,&(lvalues[5653]),0},
+{"gost94cc","GOST 34.10-94 Cryptocom",NID_id_GostR3410_94_cc,8,
+	&(lvalues[5661]),0},
+{"gost2001cc","GOST 34.10-2001 Cryptocom",NID_id_GostR3410_2001_cc,8,
+	&(lvalues[5669]),0},
+{"id-GostR3411-94-with-GostR3410-94-cc",
+	"GOST R 34.11-94 with GOST R 34.10-94 Cryptocom",
+	NID_id_GostR3411_94_with_GostR3410_94_cc,8,&(lvalues[5677]),0},
+{"id-GostR3411-94-with-GostR3410-2001-cc",
+	"GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom",
+	NID_id_GostR3411_94_with_GostR3410_2001_cc,8,&(lvalues[5685]),0},
+{"id-GostR3410-2001-ParamSet-cc",
+	"GOST R 3410-2001 Parameter Set Cryptocom",
+	NID_id_GostR3410_2001_ParamSet_cc,8,&(lvalues[5693]),0},
+{"HMAC","hmac",NID_hmac,0,NULL,0},
+{"LocalKeySet","Microsoft Local Key set",NID_LocalKeySet,9,
+	&(lvalues[5701]),0},
+{"freshestCRL","X509v3 Freshest CRL",NID_freshest_crl,3,
+	&(lvalues[5710]),0},
+{"id-on-permanentIdentifier","Permanent Identifier",
+	NID_id_on_permanentIdentifier,8,&(lvalues[5713]),0},
 };
 
 static ASN1_OBJECT *sn_objs[NUM_SN]={
@@ -2119,6 +2342,7 @@
 &(nid_objs[67]),/* "DSA-old" */
 &(nid_objs[297]),/* "DVCS" */
 &(nid_objs[99]),/* "GN" */
+&(nid_objs[855]),/* "HMAC" */
 &(nid_objs[780]),/* "HMAC-MD5" */
 &(nid_objs[781]),/* "HMAC-SHA1" */
 &(nid_objs[381]),/* "IANA" */
@@ -2132,6 +2356,7 @@
 &(nid_objs[646]),/* "JOINT-ISO-ITU-T" */
 &(nid_objs[773]),/* "KISA" */
 &(nid_objs[15]),/* "L" */
+&(nid_objs[856]),/* "LocalKeySet" */
 &(nid_objs[ 3]),/* "MD2" */
 &(nid_objs[257]),/* "MD4" */
 &(nid_objs[ 4]),/* "MD5" */
@@ -2275,6 +2500,8 @@
 &(nid_objs[153]),/* "crlBag" */
 &(nid_objs[103]),/* "crlDistributionPoints" */
 &(nid_objs[88]),/* "crlNumber" */
+&(nid_objs[806]),/* "cryptocom" */
+&(nid_objs[805]),/* "cryptopro" */
 &(nid_objs[500]),/* "dITRedirect" */
 &(nid_objs[451]),/* "dNSDomain" */
 &(nid_objs[495]),/* "dSAQuality" */
@@ -2295,7 +2522,15 @@
 &(nid_objs[470]),/* "documentVersion" */
 &(nid_objs[392]),/* "domain" */
 &(nid_objs[452]),/* "domainRelatedObject" */
+&(nid_objs[802]),/* "dsa_with_SHA224" */
+&(nid_objs[803]),/* "dsa_with_SHA256" */
+&(nid_objs[791]),/* "ecdsa-with-Recommended" */
 &(nid_objs[416]),/* "ecdsa-with-SHA1" */
+&(nid_objs[793]),/* "ecdsa-with-SHA224" */
+&(nid_objs[794]),/* "ecdsa-with-SHA256" */
+&(nid_objs[795]),/* "ecdsa-with-SHA384" */
+&(nid_objs[796]),/* "ecdsa-with-SHA512" */
+&(nid_objs[792]),/* "ecdsa-with-Specified" */
 &(nid_objs[48]),/* "emailAddress" */
 &(nid_objs[132]),/* "emailProtection" */
 &(nid_objs[389]),/* "enterprises" */
@@ -2305,11 +2540,24 @@
 &(nid_objs[126]),/* "extendedKeyUsage" */
 &(nid_objs[372]),/* "extendedStatus" */
 &(nid_objs[462]),/* "favouriteDrink" */
+&(nid_objs[857]),/* "freshestCRL" */
 &(nid_objs[453]),/* "friendlyCountry" */
 &(nid_objs[490]),/* "friendlyCountryName" */
 &(nid_objs[156]),/* "friendlyName" */
 &(nid_objs[509]),/* "generationQualifier" */
+&(nid_objs[815]),/* "gost-mac" */
+&(nid_objs[811]),/* "gost2001" */
+&(nid_objs[851]),/* "gost2001cc" */
+&(nid_objs[813]),/* "gost89" */
+&(nid_objs[814]),/* "gost89-cnt" */
+&(nid_objs[812]),/* "gost94" */
+&(nid_objs[850]),/* "gost94cc" */
+&(nid_objs[797]),/* "hmacWithMD5" */
 &(nid_objs[163]),/* "hmacWithSHA1" */
+&(nid_objs[798]),/* "hmacWithSHA224" */
+&(nid_objs[799]),/* "hmacWithSHA256" */
+&(nid_objs[800]),/* "hmacWithSHA384" */
+&(nid_objs[801]),/* "hmacWithSHA512" */
 &(nid_objs[432]),/* "holdInstructionCallIssuer" */
 &(nid_objs[430]),/* "holdInstructionCode" */
 &(nid_objs[431]),/* "holdInstructionNone" */
@@ -2319,6 +2567,45 @@
 &(nid_objs[466]),/* "host" */
 &(nid_objs[442]),/* "iA5StringSyntax" */
 &(nid_objs[783]),/* "id-DHBasedMac" */
+&(nid_objs[824]),/* "id-Gost28147-89-CryptoPro-A-ParamSet" */
+&(nid_objs[825]),/* "id-Gost28147-89-CryptoPro-B-ParamSet" */
+&(nid_objs[826]),/* "id-Gost28147-89-CryptoPro-C-ParamSet" */
+&(nid_objs[827]),/* "id-Gost28147-89-CryptoPro-D-ParamSet" */
+&(nid_objs[819]),/* "id-Gost28147-89-CryptoPro-KeyMeshing" */
+&(nid_objs[829]),/* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */
+&(nid_objs[828]),/* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */
+&(nid_objs[830]),/* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */
+&(nid_objs[820]),/* "id-Gost28147-89-None-KeyMeshing" */
+&(nid_objs[823]),/* "id-Gost28147-89-TestParamSet" */
+&(nid_objs[849]),/* "id-Gost28147-89-cc" */
+&(nid_objs[840]),/* "id-GostR3410-2001-CryptoPro-A-ParamSet" */
+&(nid_objs[841]),/* "id-GostR3410-2001-CryptoPro-B-ParamSet" */
+&(nid_objs[842]),/* "id-GostR3410-2001-CryptoPro-C-ParamSet" */
+&(nid_objs[843]),/* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */
+&(nid_objs[844]),/* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */
+&(nid_objs[854]),/* "id-GostR3410-2001-ParamSet-cc" */
+&(nid_objs[839]),/* "id-GostR3410-2001-TestParamSet" */
+&(nid_objs[817]),/* "id-GostR3410-2001DH" */
+&(nid_objs[832]),/* "id-GostR3410-94-CryptoPro-A-ParamSet" */
+&(nid_objs[833]),/* "id-GostR3410-94-CryptoPro-B-ParamSet" */
+&(nid_objs[834]),/* "id-GostR3410-94-CryptoPro-C-ParamSet" */
+&(nid_objs[835]),/* "id-GostR3410-94-CryptoPro-D-ParamSet" */
+&(nid_objs[836]),/* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */
+&(nid_objs[837]),/* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */
+&(nid_objs[838]),/* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */
+&(nid_objs[831]),/* "id-GostR3410-94-TestParamSet" */
+&(nid_objs[845]),/* "id-GostR3410-94-a" */
+&(nid_objs[846]),/* "id-GostR3410-94-aBis" */
+&(nid_objs[847]),/* "id-GostR3410-94-b" */
+&(nid_objs[848]),/* "id-GostR3410-94-bBis" */
+&(nid_objs[818]),/* "id-GostR3410-94DH" */
+&(nid_objs[822]),/* "id-GostR3411-94-CryptoProParamSet" */
+&(nid_objs[821]),/* "id-GostR3411-94-TestParamSet" */
+&(nid_objs[807]),/* "id-GostR3411-94-with-GostR3410-2001" */
+&(nid_objs[853]),/* "id-GostR3411-94-with-GostR3410-2001-cc" */
+&(nid_objs[808]),/* "id-GostR3411-94-with-GostR3410-94" */
+&(nid_objs[852]),/* "id-GostR3411-94-with-GostR3410-94-cc" */
+&(nid_objs[810]),/* "id-HMACGostR3411-94" */
 &(nid_objs[782]),/* "id-PasswordBasedMAC" */
 &(nid_objs[266]),/* "id-aca" */
 &(nid_objs[355]),/* "id-aca-accessIdentity" */
@@ -2398,6 +2685,7 @@
 &(nid_objs[279]),/* "id-mod-qualified-cert-93" */
 &(nid_objs[281]),/* "id-mod-timestamp-protocol" */
 &(nid_objs[264]),/* "id-on" */
+&(nid_objs[858]),/* "id-on-permanentIdentifier" */
 &(nid_objs[347]),/* "id-on-personalData" */
 &(nid_objs[265]),/* "id-pda" */
 &(nid_objs[352]),/* "id-pda-countryOfCitizenship" */
@@ -2522,6 +2810,7 @@
 &(nid_objs[460]),/* "mail" */
 &(nid_objs[493]),/* "mailPreferenceOption" */
 &(nid_objs[467]),/* "manager" */
+&(nid_objs[809]),/* "md_gost94" */
 &(nid_objs[182]),/* "member-body" */
 &(nid_objs[51]),/* "messageDigest" */
 &(nid_objs[383]),/* "mgmt" */
@@ -2590,6 +2879,7 @@
 &(nid_objs[747]),/* "policyMappings" */
 &(nid_objs[661]),/* "postalCode" */
 &(nid_objs[683]),/* "ppBasis" */
+&(nid_objs[816]),/* "prf-gostr3411-94" */
 &(nid_objs[406]),/* "prime-field" */
 &(nid_objs[409]),/* "prime192v1" */
 &(nid_objs[410]),/* "prime192v2" */
@@ -2823,6 +3113,7 @@
 &(nid_objs[740]),/* "wap-wsg-idm-ecid-wtls7" */
 &(nid_objs[741]),/* "wap-wsg-idm-ecid-wtls8" */
 &(nid_objs[742]),/* "wap-wsg-idm-ecid-wtls9" */
+&(nid_objs[804]),/* "whirlpool" */
 &(nid_objs[503]),/* "x500UniqueIdentifier" */
 &(nid_objs[158]),/* "x509Certificate" */
 &(nid_objs[160]),/* "x509Crl" */
@@ -2847,6 +3138,23 @@
 &(nid_objs[384]),/* "Experimental" */
 &(nid_objs[372]),/* "Extended OCSP Status" */
 &(nid_objs[172]),/* "Extension Request" */
+&(nid_objs[813]),/* "GOST 28147-89" */
+&(nid_objs[849]),/* "GOST 28147-89 Cryptocom ParamSet" */
+&(nid_objs[815]),/* "GOST 28147-89 MAC" */
+&(nid_objs[851]),/* "GOST 34.10-2001 Cryptocom" */
+&(nid_objs[850]),/* "GOST 34.10-94 Cryptocom" */
+&(nid_objs[811]),/* "GOST R 34.10-2001" */
+&(nid_objs[817]),/* "GOST R 34.10-2001 DH" */
+&(nid_objs[812]),/* "GOST R 34.10-94" */
+&(nid_objs[818]),/* "GOST R 34.10-94 DH" */
+&(nid_objs[809]),/* "GOST R 34.11-94" */
+&(nid_objs[816]),/* "GOST R 34.11-94 PRF" */
+&(nid_objs[807]),/* "GOST R 34.11-94 with GOST R 34.10-2001" */
+&(nid_objs[853]),/* "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" */
+&(nid_objs[808]),/* "GOST R 34.11-94 with GOST R 34.10-94" */
+&(nid_objs[852]),/* "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" */
+&(nid_objs[854]),/* "GOST R 3410-2001 Parameter Set Cryptocom" */
+&(nid_objs[810]),/* "HMAC GOST 34.11-94" */
 &(nid_objs[432]),/* "Hold Instruction Call Issuer" */
 &(nid_objs[430]),/* "Hold Instruction Code" */
 &(nid_objs[431]),/* "Hold Instruction None" */
@@ -2869,6 +3177,7 @@
 &(nid_objs[138]),/* "Microsoft Encrypted File System" */
 &(nid_objs[171]),/* "Microsoft Extension Request" */
 &(nid_objs[134]),/* "Microsoft Individual Code Signing" */
+&(nid_objs[856]),/* "Microsoft Local Key set" */
 &(nid_objs[137]),/* "Microsoft Server Gated Crypto" */
 &(nid_objs[648]),/* "Microsoft Smartcardlogin" */
 &(nid_objs[136]),/* "Microsoft Trust List Signing" */
@@ -2899,6 +3208,7 @@
 &(nid_objs[69]),/* "PBKDF2" */
 &(nid_objs[162]),/* "PBMAC1" */
 &(nid_objs[127]),/* "PKIX" */
+&(nid_objs[858]),/* "Permanent Identifier" */
 &(nid_objs[164]),/* "Policy Qualifier CPS" */
 &(nid_objs[165]),/* "Policy Qualifier User Notice" */
 &(nid_objs[385]),/* "Private" */
@@ -2929,6 +3239,7 @@
 &(nid_objs[89]),/* "X509v3 Certificate Policies" */
 &(nid_objs[140]),/* "X509v3 Delta CRL Indicator" */
 &(nid_objs[126]),/* "X509v3 Extended Key Usage" */
+&(nid_objs[857]),/* "X509v3 Freshest CRL" */
 &(nid_objs[748]),/* "X509v3 Inhibit Any Policy" */
 &(nid_objs[86]),/* "X509v3 Issuer Alternative Name" */
 &(nid_objs[770]),/* "X509v3 Issuing Distrubution Point" */
@@ -3035,6 +3346,8 @@
 &(nid_objs[53]),/* "countersignature" */
 &(nid_objs[14]),/* "countryName" */
 &(nid_objs[153]),/* "crlBag" */
+&(nid_objs[806]),/* "cryptocom" */
+&(nid_objs[805]),/* "cryptopro" */
 &(nid_objs[500]),/* "dITRedirect" */
 &(nid_objs[451]),/* "dNSDomain" */
 &(nid_objs[495]),/* "dSAQuality" */
@@ -3079,8 +3392,16 @@
 &(nid_objs[66]),/* "dsaWithSHA" */
 &(nid_objs[113]),/* "dsaWithSHA1" */
 &(nid_objs[70]),/* "dsaWithSHA1-old" */
+&(nid_objs[802]),/* "dsa_with_SHA224" */
+&(nid_objs[803]),/* "dsa_with_SHA256" */
 &(nid_objs[297]),/* "dvcs" */
+&(nid_objs[791]),/* "ecdsa-with-Recommended" */
 &(nid_objs[416]),/* "ecdsa-with-SHA1" */
+&(nid_objs[793]),/* "ecdsa-with-SHA224" */
+&(nid_objs[794]),/* "ecdsa-with-SHA256" */
+&(nid_objs[795]),/* "ecdsa-with-SHA384" */
+&(nid_objs[796]),/* "ecdsa-with-SHA512" */
+&(nid_objs[792]),/* "ecdsa-with-Specified" */
 &(nid_objs[48]),/* "emailAddress" */
 &(nid_objs[632]),/* "encrypted track 2" */
 &(nid_objs[56]),/* "extendedCertificateAttributes" */
@@ -3092,14 +3413,51 @@
 &(nid_objs[509]),/* "generationQualifier" */
 &(nid_objs[601]),/* "generic cryptogram" */
 &(nid_objs[99]),/* "givenName" */
+&(nid_objs[814]),/* "gost89-cnt" */
+&(nid_objs[855]),/* "hmac" */
 &(nid_objs[780]),/* "hmac-md5" */
 &(nid_objs[781]),/* "hmac-sha1" */
+&(nid_objs[797]),/* "hmacWithMD5" */
 &(nid_objs[163]),/* "hmacWithSHA1" */
+&(nid_objs[798]),/* "hmacWithSHA224" */
+&(nid_objs[799]),/* "hmacWithSHA256" */
+&(nid_objs[800]),/* "hmacWithSHA384" */
+&(nid_objs[801]),/* "hmacWithSHA512" */
 &(nid_objs[486]),/* "homePostalAddress" */
 &(nid_objs[473]),/* "homeTelephoneNumber" */
 &(nid_objs[466]),/* "host" */
 &(nid_objs[442]),/* "iA5StringSyntax" */
 &(nid_objs[381]),/* "iana" */
+&(nid_objs[824]),/* "id-Gost28147-89-CryptoPro-A-ParamSet" */
+&(nid_objs[825]),/* "id-Gost28147-89-CryptoPro-B-ParamSet" */
+&(nid_objs[826]),/* "id-Gost28147-89-CryptoPro-C-ParamSet" */
+&(nid_objs[827]),/* "id-Gost28147-89-CryptoPro-D-ParamSet" */
+&(nid_objs[819]),/* "id-Gost28147-89-CryptoPro-KeyMeshing" */
+&(nid_objs[829]),/* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */
+&(nid_objs[828]),/* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */
+&(nid_objs[830]),/* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */
+&(nid_objs[820]),/* "id-Gost28147-89-None-KeyMeshing" */
+&(nid_objs[823]),/* "id-Gost28147-89-TestParamSet" */
+&(nid_objs[840]),/* "id-GostR3410-2001-CryptoPro-A-ParamSet" */
+&(nid_objs[841]),/* "id-GostR3410-2001-CryptoPro-B-ParamSet" */
+&(nid_objs[842]),/* "id-GostR3410-2001-CryptoPro-C-ParamSet" */
+&(nid_objs[843]),/* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */
+&(nid_objs[844]),/* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */
+&(nid_objs[839]),/* "id-GostR3410-2001-TestParamSet" */
+&(nid_objs[832]),/* "id-GostR3410-94-CryptoPro-A-ParamSet" */
+&(nid_objs[833]),/* "id-GostR3410-94-CryptoPro-B-ParamSet" */
+&(nid_objs[834]),/* "id-GostR3410-94-CryptoPro-C-ParamSet" */
+&(nid_objs[835]),/* "id-GostR3410-94-CryptoPro-D-ParamSet" */
+&(nid_objs[836]),/* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */
+&(nid_objs[837]),/* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */
+&(nid_objs[838]),/* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */
+&(nid_objs[831]),/* "id-GostR3410-94-TestParamSet" */
+&(nid_objs[845]),/* "id-GostR3410-94-a" */
+&(nid_objs[846]),/* "id-GostR3410-94-aBis" */
+&(nid_objs[847]),/* "id-GostR3410-94-b" */
+&(nid_objs[848]),/* "id-GostR3410-94-bBis" */
+&(nid_objs[822]),/* "id-GostR3411-94-CryptoProParamSet" */
+&(nid_objs[821]),/* "id-GostR3411-94-TestParamSet" */
 &(nid_objs[266]),/* "id-aca" */
 &(nid_objs[355]),/* "id-aca-accessIdentity" */
 &(nid_objs[354]),/* "id-aca-authenticationInfo" */
@@ -3609,6 +3967,7 @@
 &(nid_objs[740]),/* "wap-wsg-idm-ecid-wtls7" */
 &(nid_objs[741]),/* "wap-wsg-idm-ecid-wtls8" */
 &(nid_objs[742]),/* "wap-wsg-idm-ecid-wtls9" */
+&(nid_objs[804]),/* "whirlpool" */
 &(nid_objs[503]),/* "x500UniqueIdentifier" */
 &(nid_objs[158]),/* "x509Certificate" */
 &(nid_objs[160]),/* "x509Crl" */
@@ -3680,6 +4039,7 @@
 &(nid_objs[90]),/* OBJ_authority_key_identifier     2 5 29 35 */
 &(nid_objs[401]),/* OBJ_policy_constraints           2 5 29 36 */
 &(nid_objs[126]),/* OBJ_ext_key_usage                2 5 29 37 */
+&(nid_objs[857]),/* OBJ_freshest_crl                 2 5 29 46 */
 &(nid_objs[748]),/* OBJ_inhibit_any_policy           2 5 29 54 */
 &(nid_objs[402]),/* OBJ_target_information           2 5 29 55 */
 &(nid_objs[403]),/* OBJ_no_rev_avail                 2 5 29 56 */
@@ -3814,6 +4174,8 @@
 &(nid_objs[637]),/* OBJ_set_brand_Diners             2 23 42 8 30 */
 &(nid_objs[638]),/* OBJ_set_brand_AmericanExpress    2 23 42 8 34 */
 &(nid_objs[639]),/* OBJ_set_brand_JCB                2 23 42 8 35 */
+&(nid_objs[805]),/* OBJ_cryptopro                    1 2 643 2 2 */
+&(nid_objs[806]),/* OBJ_cryptocom                    1 2 643 2 9 */
 &(nid_objs[184]),/* OBJ_X9_57                        1 2 840 10040 */
 &(nid_objs[405]),/* OBJ_ansi_X9_62                   1 2 840 10045 */
 &(nid_objs[389]),/* OBJ_Enterprises                  1 3 6 1 4 1 */
@@ -3884,8 +4246,20 @@
 &(nid_objs[743]),/* OBJ_wap_wsg_idm_ecid_wtls10      2 23 43 13 4 10 */
 &(nid_objs[744]),/* OBJ_wap_wsg_idm_ecid_wtls11      2 23 43 13 4 11 */
 &(nid_objs[745]),/* OBJ_wap_wsg_idm_ecid_wtls12      2 23 43 13 4 12 */
+&(nid_objs[804]),/* OBJ_whirlpool                    1 0 10118 3 0 55 */
 &(nid_objs[124]),/* OBJ_rle_compression              1 1 1 1 666 1 */
 &(nid_objs[773]),/* OBJ_kisa                         1 2 410 200004 */
+&(nid_objs[807]),/* OBJ_id_GostR3411_94_with_GostR3410_2001 1 2 643 2 2 3 */
+&(nid_objs[808]),/* OBJ_id_GostR3411_94_with_GostR3410_94 1 2 643 2 2 4 */
+&(nid_objs[809]),/* OBJ_id_GostR3411_94              1 2 643 2 2 9 */
+&(nid_objs[810]),/* OBJ_id_HMACGostR3411_94          1 2 643 2 2 10 */
+&(nid_objs[811]),/* OBJ_id_GostR3410_2001            1 2 643 2 2 19 */
+&(nid_objs[812]),/* OBJ_id_GostR3410_94              1 2 643 2 2 20 */
+&(nid_objs[813]),/* OBJ_id_Gost28147_89              1 2 643 2 2 21 */
+&(nid_objs[815]),/* OBJ_id_Gost28147_89_MAC          1 2 643 2 2 22 */
+&(nid_objs[816]),/* OBJ_id_GostR3411_94_prf          1 2 643 2 2 23 */
+&(nid_objs[817]),/* OBJ_id_GostR3410_2001DH          1 2 643 2 2 98 */
+&(nid_objs[818]),/* OBJ_id_GostR3410_94DH            1 2 643 2 2 99 */
 &(nid_objs[ 1]),/* OBJ_rsadsi                       1 2 840 113549 */
 &(nid_objs[185]),/* OBJ_X9cm                         1 2 840 10040 4 */
 &(nid_objs[127]),/* OBJ_id_pkix                      1 3 6 1 5 5 7 */
@@ -3898,6 +4272,36 @@
 &(nid_objs[634]),/* OBJ_setAttr_TokICCsig            2 23 42 3 3 5 1 */
 &(nid_objs[635]),/* OBJ_setAttr_SecDevSig            2 23 42 3 3 5 2 */
 &(nid_objs[436]),/* OBJ_ucl                          0 9 2342 19200300 */
+&(nid_objs[820]),/* OBJ_id_Gost28147_89_None_KeyMeshing 1 2 643 2 2 14 0 */
+&(nid_objs[819]),/* OBJ_id_Gost28147_89_CryptoPro_KeyMeshing 1 2 643 2 2 14 1 */
+&(nid_objs[845]),/* OBJ_id_GostR3410_94_a            1 2 643 2 2 20 1 */
+&(nid_objs[846]),/* OBJ_id_GostR3410_94_aBis         1 2 643 2 2 20 2 */
+&(nid_objs[847]),/* OBJ_id_GostR3410_94_b            1 2 643 2 2 20 3 */
+&(nid_objs[848]),/* OBJ_id_GostR3410_94_bBis         1 2 643 2 2 20 4 */
+&(nid_objs[821]),/* OBJ_id_GostR3411_94_TestParamSet 1 2 643 2 2 30 0 */
+&(nid_objs[822]),/* OBJ_id_GostR3411_94_CryptoProParamSet 1 2 643 2 2 30 1 */
+&(nid_objs[823]),/* OBJ_id_Gost28147_89_TestParamSet 1 2 643 2 2 31 0 */
+&(nid_objs[824]),/* OBJ_id_Gost28147_89_CryptoPro_A_ParamSet 1 2 643 2 2 31 1 */
+&(nid_objs[825]),/* OBJ_id_Gost28147_89_CryptoPro_B_ParamSet 1 2 643 2 2 31 2 */
+&(nid_objs[826]),/* OBJ_id_Gost28147_89_CryptoPro_C_ParamSet 1 2 643 2 2 31 3 */
+&(nid_objs[827]),/* OBJ_id_Gost28147_89_CryptoPro_D_ParamSet 1 2 643 2 2 31 4 */
+&(nid_objs[828]),/* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 1 2 643 2 2 31 5 */
+&(nid_objs[829]),/* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 1 2 643 2 2 31 6 */
+&(nid_objs[830]),/* OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 1 2 643 2 2 31 7 */
+&(nid_objs[831]),/* OBJ_id_GostR3410_94_TestParamSet 1 2 643 2 2 32 0 */
+&(nid_objs[832]),/* OBJ_id_GostR3410_94_CryptoPro_A_ParamSet 1 2 643 2 2 32 2 */
+&(nid_objs[833]),/* OBJ_id_GostR3410_94_CryptoPro_B_ParamSet 1 2 643 2 2 32 3 */
+&(nid_objs[834]),/* OBJ_id_GostR3410_94_CryptoPro_C_ParamSet 1 2 643 2 2 32 4 */
+&(nid_objs[835]),/* OBJ_id_GostR3410_94_CryptoPro_D_ParamSet 1 2 643 2 2 32 5 */
+&(nid_objs[836]),/* OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet 1 2 643 2 2 33 1 */
+&(nid_objs[837]),/* OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet 1 2 643 2 2 33 2 */
+&(nid_objs[838]),/* OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet 1 2 643 2 2 33 3 */
+&(nid_objs[839]),/* OBJ_id_GostR3410_2001_TestParamSet 1 2 643 2 2 35 0 */
+&(nid_objs[840]),/* OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet 1 2 643 2 2 35 1 */
+&(nid_objs[841]),/* OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet 1 2 643 2 2 35 2 */
+&(nid_objs[842]),/* OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet 1 2 643 2 2 35 3 */
+&(nid_objs[843]),/* OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet 1 2 643 2 2 36 0 */
+&(nid_objs[844]),/* OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet 1 2 643 2 2 36 1 */
 &(nid_objs[ 2]),/* OBJ_pkcs                         1 2 840 113549 1 */
 &(nid_objs[431]),/* OBJ_hold_instruction_none        1 2 840 10040 2 1 */
 &(nid_objs[432]),/* OBJ_hold_instruction_call_issuer 1 2 840 10040 2 2 */
@@ -3908,6 +4312,8 @@
 &(nid_objs[407]),/* OBJ_X9_62_characteristic_two_field 1 2 840 10045 1 2 */
 &(nid_objs[408]),/* OBJ_X9_62_id_ecPublicKey         1 2 840 10045 2 1 */
 &(nid_objs[416]),/* OBJ_ecdsa_with_SHA1              1 2 840 10045 4 1 */
+&(nid_objs[791]),/* OBJ_ecdsa_with_Recommended       1 2 840 10045 4 2 */
+&(nid_objs[792]),/* OBJ_ecdsa_with_Specified         1 2 840 10045 4 3 */
 &(nid_objs[258]),/* OBJ_id_pkix_mod                  1 3 6 1 5 5 7 0 */
 &(nid_objs[175]),/* OBJ_id_pe                        1 3 6 1 5 5 7 1 */
 &(nid_objs[259]),/* OBJ_id_qt                        1 3 6 1 5 5 7 2 */
@@ -3940,6 +4346,12 @@
 &(nid_objs[777]),/* OBJ_seed_cbc                     1 2 410 200004 1 4 */
 &(nid_objs[779]),/* OBJ_seed_cfb128                  1 2 410 200004 1 5 */
 &(nid_objs[778]),/* OBJ_seed_ofb128                  1 2 410 200004 1 6 */
+&(nid_objs[852]),/* OBJ_id_GostR3411_94_with_GostR3410_94_cc 1 2 643 2 9 1 3 3 */
+&(nid_objs[853]),/* OBJ_id_GostR3411_94_with_GostR3410_2001_cc 1 2 643 2 9 1 3 4 */
+&(nid_objs[850]),/* OBJ_id_GostR3410_94_cc           1 2 643 2 9 1 5 3 */
+&(nid_objs[851]),/* OBJ_id_GostR3410_2001_cc         1 2 643 2 9 1 5 4 */
+&(nid_objs[849]),/* OBJ_id_Gost28147_89_cc           1 2 643 2 9 1 6 1 */
+&(nid_objs[854]),/* OBJ_id_GostR3410_2001_ParamSet_cc 1 2 643 2 9 1 8 1 */
 &(nid_objs[186]),/* OBJ_pkcs1                        1 2 840 113549 1 1 */
 &(nid_objs[27]),/* OBJ_pkcs3                        1 2 840 113549 1 3 */
 &(nid_objs[187]),/* OBJ_pkcs5                        1 2 840 113549 1 5 */
@@ -3948,7 +4360,12 @@
 &(nid_objs[ 3]),/* OBJ_md2                          1 2 840 113549 2 2 */
 &(nid_objs[257]),/* OBJ_md4                          1 2 840 113549 2 4 */
 &(nid_objs[ 4]),/* OBJ_md5                          1 2 840 113549 2 5 */
+&(nid_objs[797]),/* OBJ_hmacWithMD5                  1 2 840 113549 2 6 */
 &(nid_objs[163]),/* OBJ_hmacWithSHA1                 1 2 840 113549 2 7 */
+&(nid_objs[798]),/* OBJ_hmacWithSHA224               1 2 840 113549 2 8 */
+&(nid_objs[799]),/* OBJ_hmacWithSHA256               1 2 840 113549 2 9 */
+&(nid_objs[800]),/* OBJ_hmacWithSHA384               1 2 840 113549 2 10 */
+&(nid_objs[801]),/* OBJ_hmacWithSHA512               1 2 840 113549 2 11 */
 &(nid_objs[37]),/* OBJ_rc2_cbc                      1 2 840 113549 3 2 */
 &(nid_objs[ 5]),/* OBJ_rc4                          1 2 840 113549 3 4 */
 &(nid_objs[44]),/* OBJ_des_ede3_cbc                 1 2 840 113549 3 7 */
@@ -3982,6 +4399,10 @@
 &(nid_objs[413]),/* OBJ_X9_62_prime239v2             1 2 840 10045 3 1 5 */
 &(nid_objs[414]),/* OBJ_X9_62_prime239v3             1 2 840 10045 3 1 6 */
 &(nid_objs[415]),/* OBJ_X9_62_prime256v1             1 2 840 10045 3 1 7 */
+&(nid_objs[793]),/* OBJ_ecdsa_with_SHA224            1 2 840 10045 4 3 1 */
+&(nid_objs[794]),/* OBJ_ecdsa_with_SHA256            1 2 840 10045 4 3 2 */
+&(nid_objs[795]),/* OBJ_ecdsa_with_SHA384            1 2 840 10045 4 3 3 */
+&(nid_objs[796]),/* OBJ_ecdsa_with_SHA512            1 2 840 10045 4 3 4 */
 &(nid_objs[269]),/* OBJ_id_pkix1_explicit_88         1 3 6 1 5 5 7 0 1 */
 &(nid_objs[270]),/* OBJ_id_pkix1_implicit_88         1 3 6 1 5 5 7 0 2 */
 &(nid_objs[271]),/* OBJ_id_pkix1_explicit_93         1 3 6 1 5 5 7 0 3 */
@@ -4066,6 +4487,7 @@
 &(nid_objs[345]),/* OBJ_id_cmc_popLinkWitness        1 3 6 1 5 5 7 7 23 */
 &(nid_objs[346]),/* OBJ_id_cmc_confirmCertAcceptance 1 3 6 1 5 5 7 7 24 */
 &(nid_objs[347]),/* OBJ_id_on_personalData           1 3 6 1 5 5 7 8 1 */
+&(nid_objs[858]),/* OBJ_id_on_permanentIdentifier    1 3 6 1 5 5 7 8 3 */
 &(nid_objs[348]),/* OBJ_id_pda_dateOfBirth           1 3 6 1 5 5 7 9 1 */
 &(nid_objs[349]),/* OBJ_id_pda_placeOfBirth          1 3 6 1 5 5 7 9 2 */
 &(nid_objs[351]),/* OBJ_id_pda_gender                1 3 6 1 5 5 7 9 3 */
@@ -4145,6 +4567,7 @@
 &(nid_objs[682]),/* OBJ_X9_62_tpBasis                1 2 840 10045 1 2 3 2 */
 &(nid_objs[683]),/* OBJ_X9_62_ppBasis                1 2 840 10045 1 2 3 3 */
 &(nid_objs[417]),/* OBJ_ms_csp_name                  1 3 6 1 4 1 311 17 1 */
+&(nid_objs[856]),/* OBJ_LocalKeySet                  1 3 6 1 4 1 311 17 2 */
 &(nid_objs[390]),/* OBJ_dcObject                     1 3 6 1 4 1 1466 344 */
 &(nid_objs[91]),/* OBJ_bf_cbc                       1 3 6 1 4 1 3029 1 2 */
 &(nid_objs[315]),/* OBJ_id_regCtrl_regToken          1 3 6 1 5 5 7 5 1 1 */
@@ -4185,6 +4608,8 @@
 &(nid_objs[673]),/* OBJ_sha384                       2 16 840 1 101 3 4 2 2 */
 &(nid_objs[674]),/* OBJ_sha512                       2 16 840 1 101 3 4 2 3 */
 &(nid_objs[675]),/* OBJ_sha224                       2 16 840 1 101 3 4 2 4 */
+&(nid_objs[802]),/* OBJ_dsa_with_SHA224              2 16 840 1 101 3 4 3 1 */
+&(nid_objs[803]),/* OBJ_dsa_with_SHA256              2 16 840 1 101 3 4 3 2 */
 &(nid_objs[71]),/* OBJ_netscape_cert_type           2 16 840 1 113730 1 1 */
 &(nid_objs[72]),/* OBJ_netscape_base_url            2 16 840 1 113730 1 2 */
 &(nid_objs[73]),/* OBJ_netscape_revocation_url      2 16 840 1 113730 1 3 */
diff --git a/crypto/objects/obj_dat.pl b/crypto/objects/obj_dat.pl
index 8a09a46..7de2f77 100644
--- a/crypto/objects/obj_dat.pl
+++ b/crypto/objects/obj_dat.pl
@@ -2,7 +2,9 @@
 
 # fixes bug in floating point emulation on sparc64 when
 # this script produces off-by-one output on sparc64
-use integer;
+eval 'use integer;';
+
+print STDERR "Warning: perl module integer not found.\n" if ($@);
 
 sub obj_cmp
 	{
diff --git a/crypto/objects/obj_mac.h b/crypto/objects/obj_mac.h
index 76d5ec9..ad5f7cf 100644
--- a/crypto/objects/obj_mac.h
+++ b/crypto/objects/obj_mac.h
@@ -315,6 +315,30 @@
 #define NID_ecdsa_with_SHA1		416
 #define OBJ_ecdsa_with_SHA1		OBJ_X9_62_id_ecSigType,1L
 
+#define SN_ecdsa_with_Recommended		"ecdsa-with-Recommended"
+#define NID_ecdsa_with_Recommended		791
+#define OBJ_ecdsa_with_Recommended		OBJ_X9_62_id_ecSigType,2L
+
+#define SN_ecdsa_with_Specified		"ecdsa-with-Specified"
+#define NID_ecdsa_with_Specified		792
+#define OBJ_ecdsa_with_Specified		OBJ_X9_62_id_ecSigType,3L
+
+#define SN_ecdsa_with_SHA224		"ecdsa-with-SHA224"
+#define NID_ecdsa_with_SHA224		793
+#define OBJ_ecdsa_with_SHA224		OBJ_ecdsa_with_Specified,1L
+
+#define SN_ecdsa_with_SHA256		"ecdsa-with-SHA256"
+#define NID_ecdsa_with_SHA256		794
+#define OBJ_ecdsa_with_SHA256		OBJ_ecdsa_with_Specified,2L
+
+#define SN_ecdsa_with_SHA384		"ecdsa-with-SHA384"
+#define NID_ecdsa_with_SHA384		795
+#define OBJ_ecdsa_with_SHA384		OBJ_ecdsa_with_Specified,3L
+
+#define SN_ecdsa_with_SHA512		"ecdsa-with-SHA512"
+#define NID_ecdsa_with_SHA512		796
+#define OBJ_ecdsa_with_SHA512		OBJ_ecdsa_with_Specified,4L
+
 #define OBJ_secg_ellipticCurve		OBJ_certicom_arc,0L
 
 #define SN_secp112r1		"secp112r1"
@@ -1006,6 +1030,11 @@
 #define NID_ms_csp_name		417
 #define OBJ_ms_csp_name		1L,3L,6L,1L,4L,1L,311L,17L,1L
 
+#define SN_LocalKeySet		"LocalKeySet"
+#define LN_LocalKeySet		"Microsoft Local Key set"
+#define NID_LocalKeySet		856
+#define OBJ_LocalKeySet		1L,3L,6L,1L,4L,1L,311L,17L,2L
+
 #define OBJ_certTypes		OBJ_pkcs9,22L
 
 #define LN_x509Certificate		"x509Certificate"
@@ -1103,10 +1132,30 @@
 #define LN_md5_sha1		"md5-sha1"
 #define NID_md5_sha1		114
 
+#define LN_hmacWithMD5		"hmacWithMD5"
+#define NID_hmacWithMD5		797
+#define OBJ_hmacWithMD5		OBJ_rsadsi,2L,6L
+
 #define LN_hmacWithSHA1		"hmacWithSHA1"
 #define NID_hmacWithSHA1		163
 #define OBJ_hmacWithSHA1		OBJ_rsadsi,2L,7L
 
+#define LN_hmacWithSHA224		"hmacWithSHA224"
+#define NID_hmacWithSHA224		798
+#define OBJ_hmacWithSHA224		OBJ_rsadsi,2L,8L
+
+#define LN_hmacWithSHA256		"hmacWithSHA256"
+#define NID_hmacWithSHA256		799
+#define OBJ_hmacWithSHA256		OBJ_rsadsi,2L,9L
+
+#define LN_hmacWithSHA384		"hmacWithSHA384"
+#define NID_hmacWithSHA384		800
+#define OBJ_hmacWithSHA384		OBJ_rsadsi,2L,10L
+
+#define LN_hmacWithSHA512		"hmacWithSHA512"
+#define NID_hmacWithSHA512		801
+#define OBJ_hmacWithSHA512		OBJ_rsadsi,2L,11L
+
 #define SN_rc2_cbc		"RC2-CBC"
 #define LN_rc2_cbc		"rc2-cbc"
 #define NID_rc2_cbc		37
@@ -1685,6 +1734,11 @@
 #define NID_id_on_personalData		347
 #define OBJ_id_on_personalData		OBJ_id_on,1L
 
+#define SN_id_on_permanentIdentifier		"id-on-permanentIdentifier"
+#define LN_id_on_permanentIdentifier		"Permanent Identifier"
+#define NID_id_on_permanentIdentifier		858
+#define OBJ_id_on_permanentIdentifier		OBJ_id_on,3L
+
 #define SN_id_pda_dateOfBirth		"id-pda-dateOfBirth"
 #define NID_id_pda_dateOfBirth		348
 #define OBJ_id_pda_dateOfBirth		OBJ_id_pda,1L
@@ -2186,6 +2240,11 @@
 #define NID_ext_key_usage		126
 #define OBJ_ext_key_usage		OBJ_id_ce,37L
 
+#define SN_freshest_crl		"freshestCRL"
+#define LN_freshest_crl		"X509v3 Freshest CRL"
+#define NID_freshest_crl		857
+#define OBJ_freshest_crl		OBJ_id_ce,46L
+
 #define SN_inhibit_any_policy		"inhibitAnyPolicy"
 #define LN_inhibit_any_policy		"X509v3 Inhibit Any Policy"
 #define NID_inhibit_any_policy		748
@@ -2502,6 +2561,16 @@
 #define NID_sha224		675
 #define OBJ_sha224		OBJ_nist_hashalgs,4L
 
+#define OBJ_dsa_with_sha2		OBJ_nistAlgorithms,3L
+
+#define SN_dsa_with_SHA224		"dsa_with_SHA224"
+#define NID_dsa_with_SHA224		802
+#define OBJ_dsa_with_SHA224		OBJ_dsa_with_sha2,1L
+
+#define SN_dsa_with_SHA256		"dsa_with_SHA256"
+#define NID_dsa_with_SHA256		803
+#define OBJ_dsa_with_SHA256		OBJ_dsa_with_sha2,2L
+
 #define SN_hold_instruction_code		"holdInstructionCode"
 #define LN_hold_instruction_code		"Hold Instruction Code"
 #define NID_hold_instruction_code		430
@@ -3367,6 +3436,226 @@
 #define LN_ipsec4		"ipsec4"
 #define NID_ipsec4		750
 
+#define SN_whirlpool		"whirlpool"
+#define NID_whirlpool		804
+#define OBJ_whirlpool		OBJ_iso,0L,10118L,3L,0L,55L
+
+#define SN_cryptopro		"cryptopro"
+#define NID_cryptopro		805
+#define OBJ_cryptopro		OBJ_member_body,643L,2L,2L
+
+#define SN_cryptocom		"cryptocom"
+#define NID_cryptocom		806
+#define OBJ_cryptocom		OBJ_member_body,643L,2L,9L
+
+#define SN_id_GostR3411_94_with_GostR3410_2001		"id-GostR3411-94-with-GostR3410-2001"
+#define LN_id_GostR3411_94_with_GostR3410_2001		"GOST R 34.11-94 with GOST R 34.10-2001"
+#define NID_id_GostR3411_94_with_GostR3410_2001		807
+#define OBJ_id_GostR3411_94_with_GostR3410_2001		OBJ_cryptopro,3L
+
+#define SN_id_GostR3411_94_with_GostR3410_94		"id-GostR3411-94-with-GostR3410-94"
+#define LN_id_GostR3411_94_with_GostR3410_94		"GOST R 34.11-94 with GOST R 34.10-94"
+#define NID_id_GostR3411_94_with_GostR3410_94		808
+#define OBJ_id_GostR3411_94_with_GostR3410_94		OBJ_cryptopro,4L
+
+#define SN_id_GostR3411_94		"md_gost94"
+#define LN_id_GostR3411_94		"GOST R 34.11-94"
+#define NID_id_GostR3411_94		809
+#define OBJ_id_GostR3411_94		OBJ_cryptopro,9L
+
+#define SN_id_HMACGostR3411_94		"id-HMACGostR3411-94"
+#define LN_id_HMACGostR3411_94		"HMAC GOST 34.11-94"
+#define NID_id_HMACGostR3411_94		810
+#define OBJ_id_HMACGostR3411_94		OBJ_cryptopro,10L
+
+#define SN_id_GostR3410_2001		"gost2001"
+#define LN_id_GostR3410_2001		"GOST R 34.10-2001"
+#define NID_id_GostR3410_2001		811
+#define OBJ_id_GostR3410_2001		OBJ_cryptopro,19L
+
+#define SN_id_GostR3410_94		"gost94"
+#define LN_id_GostR3410_94		"GOST R 34.10-94"
+#define NID_id_GostR3410_94		812
+#define OBJ_id_GostR3410_94		OBJ_cryptopro,20L
+
+#define SN_id_Gost28147_89		"gost89"
+#define LN_id_Gost28147_89		"GOST 28147-89"
+#define NID_id_Gost28147_89		813
+#define OBJ_id_Gost28147_89		OBJ_cryptopro,21L
+
+#define SN_gost89_cnt		"gost89-cnt"
+#define NID_gost89_cnt		814
+
+#define SN_id_Gost28147_89_MAC		"gost-mac"
+#define LN_id_Gost28147_89_MAC		"GOST 28147-89 MAC"
+#define NID_id_Gost28147_89_MAC		815
+#define OBJ_id_Gost28147_89_MAC		OBJ_cryptopro,22L
+
+#define SN_id_GostR3411_94_prf		"prf-gostr3411-94"
+#define LN_id_GostR3411_94_prf		"GOST R 34.11-94 PRF"
+#define NID_id_GostR3411_94_prf		816
+#define OBJ_id_GostR3411_94_prf		OBJ_cryptopro,23L
+
+#define SN_id_GostR3410_2001DH		"id-GostR3410-2001DH"
+#define LN_id_GostR3410_2001DH		"GOST R 34.10-2001 DH"
+#define NID_id_GostR3410_2001DH		817
+#define OBJ_id_GostR3410_2001DH		OBJ_cryptopro,98L
+
+#define SN_id_GostR3410_94DH		"id-GostR3410-94DH"
+#define LN_id_GostR3410_94DH		"GOST R 34.10-94 DH"
+#define NID_id_GostR3410_94DH		818
+#define OBJ_id_GostR3410_94DH		OBJ_cryptopro,99L
+
+#define SN_id_Gost28147_89_CryptoPro_KeyMeshing		"id-Gost28147-89-CryptoPro-KeyMeshing"
+#define NID_id_Gost28147_89_CryptoPro_KeyMeshing		819
+#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing		OBJ_cryptopro,14L,1L
+
+#define SN_id_Gost28147_89_None_KeyMeshing		"id-Gost28147-89-None-KeyMeshing"
+#define NID_id_Gost28147_89_None_KeyMeshing		820
+#define OBJ_id_Gost28147_89_None_KeyMeshing		OBJ_cryptopro,14L,0L
+
+#define SN_id_GostR3411_94_TestParamSet		"id-GostR3411-94-TestParamSet"
+#define NID_id_GostR3411_94_TestParamSet		821
+#define OBJ_id_GostR3411_94_TestParamSet		OBJ_cryptopro,30L,0L
+
+#define SN_id_GostR3411_94_CryptoProParamSet		"id-GostR3411-94-CryptoProParamSet"
+#define NID_id_GostR3411_94_CryptoProParamSet		822
+#define OBJ_id_GostR3411_94_CryptoProParamSet		OBJ_cryptopro,30L,1L
+
+#define SN_id_Gost28147_89_TestParamSet		"id-Gost28147-89-TestParamSet"
+#define NID_id_Gost28147_89_TestParamSet		823
+#define OBJ_id_Gost28147_89_TestParamSet		OBJ_cryptopro,31L,0L
+
+#define SN_id_Gost28147_89_CryptoPro_A_ParamSet		"id-Gost28147-89-CryptoPro-A-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_A_ParamSet		824
+#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet		OBJ_cryptopro,31L,1L
+
+#define SN_id_Gost28147_89_CryptoPro_B_ParamSet		"id-Gost28147-89-CryptoPro-B-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_B_ParamSet		825
+#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet		OBJ_cryptopro,31L,2L
+
+#define SN_id_Gost28147_89_CryptoPro_C_ParamSet		"id-Gost28147-89-CryptoPro-C-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_C_ParamSet		826
+#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet		OBJ_cryptopro,31L,3L
+
+#define SN_id_Gost28147_89_CryptoPro_D_ParamSet		"id-Gost28147-89-CryptoPro-D-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_D_ParamSet		827
+#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet		OBJ_cryptopro,31L,4L
+
+#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet		"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet		828
+#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet		OBJ_cryptopro,31L,5L
+
+#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet		"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet		829
+#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet		OBJ_cryptopro,31L,6L
+
+#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet		"id-Gost28147-89-CryptoPro-RIC-1-ParamSet"
+#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet		830
+#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet		OBJ_cryptopro,31L,7L
+
+#define SN_id_GostR3410_94_TestParamSet		"id-GostR3410-94-TestParamSet"
+#define NID_id_GostR3410_94_TestParamSet		831
+#define OBJ_id_GostR3410_94_TestParamSet		OBJ_cryptopro,32L,0L
+
+#define SN_id_GostR3410_94_CryptoPro_A_ParamSet		"id-GostR3410-94-CryptoPro-A-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_A_ParamSet		832
+#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet		OBJ_cryptopro,32L,2L
+
+#define SN_id_GostR3410_94_CryptoPro_B_ParamSet		"id-GostR3410-94-CryptoPro-B-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_B_ParamSet		833
+#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet		OBJ_cryptopro,32L,3L
+
+#define SN_id_GostR3410_94_CryptoPro_C_ParamSet		"id-GostR3410-94-CryptoPro-C-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_C_ParamSet		834
+#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet		OBJ_cryptopro,32L,4L
+
+#define SN_id_GostR3410_94_CryptoPro_D_ParamSet		"id-GostR3410-94-CryptoPro-D-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_D_ParamSet		835
+#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet		OBJ_cryptopro,32L,5L
+
+#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet		"id-GostR3410-94-CryptoPro-XchA-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet		836
+#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet		OBJ_cryptopro,33L,1L
+
+#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet		"id-GostR3410-94-CryptoPro-XchB-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet		837
+#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet		OBJ_cryptopro,33L,2L
+
+#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet		"id-GostR3410-94-CryptoPro-XchC-ParamSet"
+#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet		838
+#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet		OBJ_cryptopro,33L,3L
+
+#define SN_id_GostR3410_2001_TestParamSet		"id-GostR3410-2001-TestParamSet"
+#define NID_id_GostR3410_2001_TestParamSet		839
+#define OBJ_id_GostR3410_2001_TestParamSet		OBJ_cryptopro,35L,0L
+
+#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet		"id-GostR3410-2001-CryptoPro-A-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet		840
+#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet		OBJ_cryptopro,35L,1L
+
+#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet		"id-GostR3410-2001-CryptoPro-B-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet		841
+#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet		OBJ_cryptopro,35L,2L
+
+#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet		"id-GostR3410-2001-CryptoPro-C-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet		842
+#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet		OBJ_cryptopro,35L,3L
+
+#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet		"id-GostR3410-2001-CryptoPro-XchA-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet		843
+#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet		OBJ_cryptopro,36L,0L
+
+#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet		"id-GostR3410-2001-CryptoPro-XchB-ParamSet"
+#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet		844
+#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet		OBJ_cryptopro,36L,1L
+
+#define SN_id_GostR3410_94_a		"id-GostR3410-94-a"
+#define NID_id_GostR3410_94_a		845
+#define OBJ_id_GostR3410_94_a		OBJ_id_GostR3410_94,1L
+
+#define SN_id_GostR3410_94_aBis		"id-GostR3410-94-aBis"
+#define NID_id_GostR3410_94_aBis		846
+#define OBJ_id_GostR3410_94_aBis		OBJ_id_GostR3410_94,2L
+
+#define SN_id_GostR3410_94_b		"id-GostR3410-94-b"
+#define NID_id_GostR3410_94_b		847
+#define OBJ_id_GostR3410_94_b		OBJ_id_GostR3410_94,3L
+
+#define SN_id_GostR3410_94_bBis		"id-GostR3410-94-bBis"
+#define NID_id_GostR3410_94_bBis		848
+#define OBJ_id_GostR3410_94_bBis		OBJ_id_GostR3410_94,4L
+
+#define SN_id_Gost28147_89_cc		"id-Gost28147-89-cc"
+#define LN_id_Gost28147_89_cc		"GOST 28147-89 Cryptocom ParamSet"
+#define NID_id_Gost28147_89_cc		849
+#define OBJ_id_Gost28147_89_cc		OBJ_cryptocom,1L,6L,1L
+
+#define SN_id_GostR3410_94_cc		"gost94cc"
+#define LN_id_GostR3410_94_cc		"GOST 34.10-94 Cryptocom"
+#define NID_id_GostR3410_94_cc		850
+#define OBJ_id_GostR3410_94_cc		OBJ_cryptocom,1L,5L,3L
+
+#define SN_id_GostR3410_2001_cc		"gost2001cc"
+#define LN_id_GostR3410_2001_cc		"GOST 34.10-2001 Cryptocom"
+#define NID_id_GostR3410_2001_cc		851
+#define OBJ_id_GostR3410_2001_cc		OBJ_cryptocom,1L,5L,4L
+
+#define SN_id_GostR3411_94_with_GostR3410_94_cc		"id-GostR3411-94-with-GostR3410-94-cc"
+#define LN_id_GostR3411_94_with_GostR3410_94_cc		"GOST R 34.11-94 with GOST R 34.10-94 Cryptocom"
+#define NID_id_GostR3411_94_with_GostR3410_94_cc		852
+#define OBJ_id_GostR3411_94_with_GostR3410_94_cc		OBJ_cryptocom,1L,3L,3L
+
+#define SN_id_GostR3411_94_with_GostR3410_2001_cc		"id-GostR3411-94-with-GostR3410-2001-cc"
+#define LN_id_GostR3411_94_with_GostR3410_2001_cc		"GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom"
+#define NID_id_GostR3411_94_with_GostR3410_2001_cc		853
+#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc		OBJ_cryptocom,1L,3L,4L
+
+#define SN_id_GostR3410_2001_ParamSet_cc		"id-GostR3410-2001-ParamSet-cc"
+#define LN_id_GostR3410_2001_ParamSet_cc		"GOST R 3410-2001 Parameter Set Cryptocom"
+#define NID_id_GostR3410_2001_ParamSet_cc		854
+#define OBJ_id_GostR3410_2001_ParamSet_cc		OBJ_cryptocom,1L,8L,1L
+
 #define SN_camellia_128_cbc		"CAMELLIA-128-CBC"
 #define LN_camellia_128_cbc		"camellia-128-cbc"
 #define NID_camellia_128_cbc		751
@@ -3480,3 +3769,7 @@
 #define NID_seed_ofb128		778
 #define OBJ_seed_ofb128		OBJ_kisa,1L,6L
 
+#define SN_hmac		"HMAC"
+#define LN_hmac		"hmac"
+#define NID_hmac		855
+
diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num
index 47815b1..e3f56bc 100644
--- a/crypto/objects/obj_mac.num
+++ b/crypto/objects/obj_mac.num
@@ -788,3 +788,71 @@
 id_aes128_wrap		788
 id_aes192_wrap		789
 id_aes256_wrap		790
+ecdsa_with_Recommended		791
+ecdsa_with_Specified		792
+ecdsa_with_SHA224		793
+ecdsa_with_SHA256		794
+ecdsa_with_SHA384		795
+ecdsa_with_SHA512		796
+hmacWithMD5		797
+hmacWithSHA224		798
+hmacWithSHA256		799
+hmacWithSHA384		800
+hmacWithSHA512		801
+dsa_with_SHA224		802
+dsa_with_SHA256		803
+whirlpool		804
+cryptopro		805
+cryptocom		806
+id_GostR3411_94_with_GostR3410_2001		807
+id_GostR3411_94_with_GostR3410_94		808
+id_GostR3411_94		809
+id_HMACGostR3411_94		810
+id_GostR3410_2001		811
+id_GostR3410_94		812
+id_Gost28147_89		813
+gost89_cnt		814
+id_Gost28147_89_MAC		815
+id_GostR3411_94_prf		816
+id_GostR3410_2001DH		817
+id_GostR3410_94DH		818
+id_Gost28147_89_CryptoPro_KeyMeshing		819
+id_Gost28147_89_None_KeyMeshing		820
+id_GostR3411_94_TestParamSet		821
+id_GostR3411_94_CryptoProParamSet		822
+id_Gost28147_89_TestParamSet		823
+id_Gost28147_89_CryptoPro_A_ParamSet		824
+id_Gost28147_89_CryptoPro_B_ParamSet		825
+id_Gost28147_89_CryptoPro_C_ParamSet		826
+id_Gost28147_89_CryptoPro_D_ParamSet		827
+id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet		828
+id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet		829
+id_Gost28147_89_CryptoPro_RIC_1_ParamSet		830
+id_GostR3410_94_TestParamSet		831
+id_GostR3410_94_CryptoPro_A_ParamSet		832
+id_GostR3410_94_CryptoPro_B_ParamSet		833
+id_GostR3410_94_CryptoPro_C_ParamSet		834
+id_GostR3410_94_CryptoPro_D_ParamSet		835
+id_GostR3410_94_CryptoPro_XchA_ParamSet		836
+id_GostR3410_94_CryptoPro_XchB_ParamSet		837
+id_GostR3410_94_CryptoPro_XchC_ParamSet		838
+id_GostR3410_2001_TestParamSet		839
+id_GostR3410_2001_CryptoPro_A_ParamSet		840
+id_GostR3410_2001_CryptoPro_B_ParamSet		841
+id_GostR3410_2001_CryptoPro_C_ParamSet		842
+id_GostR3410_2001_CryptoPro_XchA_ParamSet		843
+id_GostR3410_2001_CryptoPro_XchB_ParamSet		844
+id_GostR3410_94_a		845
+id_GostR3410_94_aBis		846
+id_GostR3410_94_b		847
+id_GostR3410_94_bBis		848
+id_Gost28147_89_cc		849
+id_GostR3410_94_cc		850
+id_GostR3410_2001_cc		851
+id_GostR3411_94_with_GostR3410_94_cc		852
+id_GostR3411_94_with_GostR3410_2001_cc		853
+id_GostR3410_2001_ParamSet_cc		854
+hmac		855
+LocalKeySet		856
+freshest_crl		857
+id_on_permanentIdentifier		858
diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt
index 34c8d1d..a6a811b 100644
--- a/crypto/objects/objects.txt
+++ b/crypto/objects/objects.txt
@@ -79,6 +79,12 @@
 !Alias id-ecSigType ansi-X9-62 4
 !global
 X9-62_id-ecSigType 1		: ecdsa-with-SHA1
+X9-62_id-ecSigType 2		: ecdsa-with-Recommended
+X9-62_id-ecSigType 3		: ecdsa-with-Specified
+ecdsa-with-Specified 1		: ecdsa-with-SHA224
+ecdsa-with-Specified 2		: ecdsa-with-SHA256
+ecdsa-with-Specified 3		: ecdsa-with-SHA384
+ecdsa-with-Specified 4		: ecdsa-with-SHA512
 
 # SECG curve OIDs from "SEC 2: Recommended Elliptic Curve Domain Parameters"
 # (http://www.secg.org/)
@@ -313,6 +319,7 @@
 pkcs9 21		:			: localKeyID
 !Cname ms-csp-name
 1 3 6 1 4 1 311 17 1	: CSPName		: Microsoft CSP Name
+1 3 6 1 4 1 311 17 2	: LocalKeySet		: Microsoft Local Key set
 !Alias certTypes pkcs9 22
 certTypes 1		:			: x509Certificate
 certTypes 2		:			: sdsiCertificate
@@ -348,7 +355,15 @@
 rsadsi 2 4		: MD4			: md4
 rsadsi 2 5		: MD5			: md5
 			: MD5-SHA1		: md5-sha1
+rsadsi 2 6		:			: hmacWithMD5
 rsadsi 2 7		:			: hmacWithSHA1
+
+# From RFC4231
+rsadsi 2 8		:			: hmacWithSHA224
+rsadsi 2 9		:			: hmacWithSHA256
+rsadsi 2 10		:			: hmacWithSHA384
+rsadsi 2 11		:			: hmacWithSHA512
+
 rsadsi 3 2		: RC2-CBC		: rc2-cbc
 			: RC2-ECB		: rc2-ecb
 !Cname rc2-cfb64
@@ -542,6 +557,7 @@
 
 # other names
 id-on 1			: id-on-personalData
+id-on 3			: id-on-permanentIdentifier : Permanent Identifier
 
 # personal data attributes
 id-pda 1		: id-pda-dateOfBirth
@@ -711,6 +727,8 @@
 id-ce 36		: policyConstraints	: X509v3 Policy Constraints
 !Cname ext-key-usage
 id-ce 37		: extendedKeyUsage	: X509v3 Extended Key Usage
+!Cname freshest-crl
+id-ce 46		: freshestCRL		: X509v3 Freshest CRL
 !Cname inhibit-any-policy
 id-ce 54		: inhibitAnyPolicy	: X509v3 Inhibit Any Policy
 !Cname target-information
@@ -833,6 +851,11 @@
 nist_hashalgs 3		: SHA512		: sha512
 nist_hashalgs 4		: SHA224		: sha224
 
+# OIDs for dsa-with-sha224 and dsa-with-sha256
+!Alias dsa_with_sha2 nistAlgorithms 3
+dsa_with_sha2 1		: dsa_with_SHA224
+dsa_with_sha2 2		: dsa_with_SHA256
+
 # Hold instruction CRL entry extension
 !Cname hold-instruction-code
 id-ce 23		: holdInstructionCode	: Hold Instruction Code
@@ -1070,13 +1093,93 @@
 			: Oakley-EC2N-3		: ipsec3
 			: Oakley-EC2N-4		: ipsec4
 
+iso 0 10118 3 0 55	: whirlpool
+
+# GOST OIDs
+
+member-body 643 2 2	: cryptopro
+member-body 643 2 9	: cryptocom
+
+cryptopro 3		: id-GostR3411-94-with-GostR3410-2001 : GOST R 34.11-94 with GOST R 34.10-2001
+cryptopro 4		: id-GostR3411-94-with-GostR3410-94 : GOST R 34.11-94 with GOST R 34.10-94
+!Cname id-GostR3411-94
+cryptopro 9		: md_gost94		: GOST R 34.11-94
+cryptopro 10		: id-HMACGostR3411-94	: HMAC GOST 34.11-94
+!Cname id-GostR3410-2001
+cryptopro 19		: gost2001	: GOST R 34.10-2001
+!Cname id-GostR3410-94
+cryptopro 20		: gost94	: GOST R 34.10-94
+!Cname id-Gost28147-89
+cryptopro 21		: gost89 		: GOST 28147-89
+			: gost89-cnt
+!Cname id-Gost28147-89-MAC
+cryptopro 22		: gost-mac	: GOST 28147-89 MAC
+!Cname id-GostR3411-94-prf
+cryptopro 23		: prf-gostr3411-94	: GOST R 34.11-94 PRF
+cryptopro 98		: id-GostR3410-2001DH	: GOST R 34.10-2001 DH
+cryptopro 99		: id-GostR3410-94DH	: GOST R 34.10-94 DH
+
+cryptopro 14 1		: id-Gost28147-89-CryptoPro-KeyMeshing
+cryptopro 14 0		: id-Gost28147-89-None-KeyMeshing
+
+# GOST parameter set OIDs
+
+cryptopro 30 0		: id-GostR3411-94-TestParamSet
+cryptopro 30 1		: id-GostR3411-94-CryptoProParamSet
+
+cryptopro 31 0		: id-Gost28147-89-TestParamSet
+cryptopro 31 1		: id-Gost28147-89-CryptoPro-A-ParamSet
+cryptopro 31 2		: id-Gost28147-89-CryptoPro-B-ParamSet
+cryptopro 31 3		: id-Gost28147-89-CryptoPro-C-ParamSet
+cryptopro 31 4		: id-Gost28147-89-CryptoPro-D-ParamSet
+cryptopro 31 5		: id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet
+cryptopro 31 6		: id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet
+cryptopro 31 7		: id-Gost28147-89-CryptoPro-RIC-1-ParamSet
+
+cryptopro 32 0		: id-GostR3410-94-TestParamSet
+cryptopro 32 2		: id-GostR3410-94-CryptoPro-A-ParamSet
+cryptopro 32 3		: id-GostR3410-94-CryptoPro-B-ParamSet
+cryptopro 32 4		: id-GostR3410-94-CryptoPro-C-ParamSet
+cryptopro 32 5		: id-GostR3410-94-CryptoPro-D-ParamSet
+
+cryptopro 33 1		: id-GostR3410-94-CryptoPro-XchA-ParamSet
+cryptopro 33 2		: id-GostR3410-94-CryptoPro-XchB-ParamSet
+cryptopro 33 3		: id-GostR3410-94-CryptoPro-XchC-ParamSet
+
+cryptopro 35 0		: id-GostR3410-2001-TestParamSet
+cryptopro 35 1		: id-GostR3410-2001-CryptoPro-A-ParamSet
+cryptopro 35 2		: id-GostR3410-2001-CryptoPro-B-ParamSet
+cryptopro 35 3		: id-GostR3410-2001-CryptoPro-C-ParamSet
+
+cryptopro 36 0		: id-GostR3410-2001-CryptoPro-XchA-ParamSet
+cryptopro 36 1		: id-GostR3410-2001-CryptoPro-XchB-ParamSet
+
+id-GostR3410-94 1	: id-GostR3410-94-a
+id-GostR3410-94 2	: id-GostR3410-94-aBis
+id-GostR3410-94 3	: id-GostR3410-94-b
+id-GostR3410-94 4	: id-GostR3410-94-bBis
+
+# Cryptocom LTD GOST OIDs
+
+cryptocom 1 6 1		: id-Gost28147-89-cc	: GOST 28147-89 Cryptocom ParamSet
+!Cname id-GostR3410-94-cc
+cryptocom 1 5 3		: gost94cc	: GOST 34.10-94 Cryptocom
+!Cname id-GostR3410-2001-cc
+cryptocom 1 5 4		: gost2001cc	: GOST 34.10-2001 Cryptocom
+
+cryptocom 1 3 3		: id-GostR3411-94-with-GostR3410-94-cc : GOST R 34.11-94 with GOST R 34.10-94 Cryptocom
+cryptocom 1 3 4		: id-GostR3411-94-with-GostR3410-2001-cc : GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom
+
+cryptocom 1 8 1		: id-GostR3410-2001-ParamSet-cc : GOST R 3410-2001 Parameter Set Cryptocom
 
 # Definitions for Camellia cipher - CBC MODE
+
 1 2 392 200011 61 1 1 1 2 : CAMELLIA-128-CBC		: camellia-128-cbc
 1 2 392 200011 61 1 1 1 3 : CAMELLIA-192-CBC		: camellia-192-cbc
 1 2 392 200011 61 1 1 1 4 : CAMELLIA-256-CBC		: camellia-256-cbc
 
 # Definitions for Camellia cipher - ECB, CFB, OFB MODE
+
 !Alias ntt-ds 0 3 4401 5
 !Alias camellia ntt-ds 3 1 9 
 
@@ -1107,7 +1210,6 @@
 			: CAMELLIA-192-CFB8		: camellia-192-cfb8
 			: CAMELLIA-256-CFB8		: camellia-256-cfb8
 
-
 # Definitions for SEED cipher - ECB, CBC, OFB mode
 
 member-body 410 200004  : KISA          : kisa
@@ -1117,3 +1219,7 @@
 kisa 1 5                : SEED-CFB      : seed-cfb
 !Cname seed-ofb128
 kisa 1 6                : SEED-OFB      : seed-ofb
+
+# There is no OID that just denotes "HMAC" oddly enough...
+
+			: HMAC				: hmac
diff --git a/crypto/ocsp/Makefile b/crypto/ocsp/Makefile
index 0fe0289..30a00b3 100644
--- a/crypto/ocsp/Makefile
+++ b/crypto/ocsp/Makefile
@@ -36,7 +36,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -82,9 +82,10 @@
 ocsp_asn.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
 ocsp_asn.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 ocsp_asn.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
-ocsp_asn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-ocsp_asn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-ocsp_asn.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
+ocsp_asn.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+ocsp_asn.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ocsp_asn.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
+ocsp_asn.o: ../../include/openssl/opensslconf.h
 ocsp_asn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 ocsp_asn.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 ocsp_asn.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -97,24 +98,25 @@
 ocsp_cl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 ocsp_cl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 ocsp_cl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-ocsp_cl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-ocsp_cl.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
-ocsp_cl.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-ocsp_cl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
-ocsp_cl.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
-ocsp_cl.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-ocsp_cl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-ocsp_cl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-ocsp_cl.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-ocsp_cl.o: ../cryptlib.h ocsp_cl.c
+ocsp_cl.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+ocsp_cl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+ocsp_cl.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
+ocsp_cl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ocsp_cl.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+ocsp_cl.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+ocsp_cl.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+ocsp_cl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+ocsp_cl.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+ocsp_cl.o: ../../include/openssl/x509v3.h ../cryptlib.h ocsp_cl.c
 ocsp_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 ocsp_err.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
 ocsp_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 ocsp_err.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 ocsp_err.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-ocsp_err.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-ocsp_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-ocsp_err.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
+ocsp_err.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+ocsp_err.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ocsp_err.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
+ocsp_err.o: ../../include/openssl/opensslconf.h
 ocsp_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 ocsp_err.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 ocsp_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -127,21 +129,22 @@
 ocsp_ext.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 ocsp_ext.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 ocsp_ext.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-ocsp_ext.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-ocsp_ext.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
-ocsp_ext.o: ../../include/openssl/opensslconf.h
+ocsp_ext.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+ocsp_ext.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+ocsp_ext.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
 ocsp_ext.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 ocsp_ext.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
 ocsp_ext.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 ocsp_ext.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 ocsp_ext.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
 ocsp_ext.o: ../../include/openssl/x509v3.h ../cryptlib.h ocsp_ext.c
-ocsp_ht.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-ocsp_ht.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
-ocsp_ht.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-ocsp_ht.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
-ocsp_ht.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-ocsp_ht.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
+ocsp_ht.o: ../../e_os.h ../../include/openssl/asn1.h
+ocsp_ht.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+ocsp_ht.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+ocsp_ht.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ocsp_ht.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+ocsp_ht.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+ocsp_ht.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
 ocsp_ht.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 ocsp_ht.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
 ocsp_ht.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
@@ -156,9 +159,9 @@
 ocsp_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 ocsp_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 ocsp_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-ocsp_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-ocsp_lib.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
-ocsp_lib.o: ../../include/openssl/opensslconf.h
+ocsp_lib.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+ocsp_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+ocsp_lib.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
 ocsp_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 ocsp_lib.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
 ocsp_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
@@ -171,9 +174,10 @@
 ocsp_prn.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 ocsp_prn.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 ocsp_prn.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-ocsp_prn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-ocsp_prn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-ocsp_prn.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
+ocsp_prn.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+ocsp_prn.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ocsp_prn.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
+ocsp_prn.o: ../../include/openssl/opensslconf.h
 ocsp_prn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 ocsp_prn.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
 ocsp_prn.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
@@ -187,9 +191,9 @@
 ocsp_srv.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 ocsp_srv.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 ocsp_srv.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-ocsp_srv.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-ocsp_srv.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
-ocsp_srv.o: ../../include/openssl/opensslconf.h
+ocsp_srv.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+ocsp_srv.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+ocsp_srv.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
 ocsp_srv.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 ocsp_srv.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
 ocsp_srv.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
@@ -202,9 +206,10 @@
 ocsp_vfy.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 ocsp_vfy.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 ocsp_vfy.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-ocsp_vfy.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-ocsp_vfy.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-ocsp_vfy.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
+ocsp_vfy.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+ocsp_vfy.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+ocsp_vfy.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
+ocsp_vfy.o: ../../include/openssl/opensslconf.h
 ocsp_vfy.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 ocsp_vfy.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 ocsp_vfy.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
diff --git a/crypto/ocsp/ocsp_asn.c b/crypto/ocsp/ocsp_asn.c
index 39b7a1c..bfe892a 100644
--- a/crypto/ocsp/ocsp_asn.c
+++ b/crypto/ocsp/ocsp_asn.c
@@ -1,5 +1,5 @@
 /* ocsp_asn.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/crypto/ocsp/ocsp_ht.c b/crypto/ocsp/ocsp_ht.c
index a8e569b..6abb30b 100644
--- a/crypto/ocsp/ocsp_ht.c
+++ b/crypto/ocsp/ocsp_ht.c
@@ -1,5 +1,5 @@
 /* ocsp_ht.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2006.
  */
 /* ====================================================================
@@ -56,11 +56,12 @@
  *
  */
 
-#include <openssl/asn1.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
 #include <string.h>
+#include "e_os.h"
+#include <openssl/asn1.h>
 #include <openssl/ocsp.h>
 #include <openssl/err.h>
 #include <openssl/buffer.h>
diff --git a/crypto/ocsp/ocsp_srv.c b/crypto/ocsp/ocsp_srv.c
index fffa134..1c606dd 100644
--- a/crypto/ocsp/ocsp_srv.c
+++ b/crypto/ocsp/ocsp_srv.c
@@ -1,5 +1,5 @@
 /* ocsp_srv.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2001.
  */
 /* ====================================================================
diff --git a/crypto/ocsp/ocsp_vfy.c b/crypto/ocsp/ocsp_vfy.c
index 23ea41c..4a0c387 100644
--- a/crypto/ocsp/ocsp_vfy.c
+++ b/crypto/ocsp/ocsp_vfy.c
@@ -1,5 +1,5 @@
 /* ocsp_vfy.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/crypto/opensslconf.h b/crypto/opensslconf.h
index 14e04f9..4aa0330 100644
--- a/crypto/opensslconf.h
+++ b/crypto/opensslconf.h
@@ -4,12 +4,16 @@
 /* OpenSSL was configured with the following options: */
 #ifndef OPENSSL_DOING_MAKEDEPEND
 
+
 #ifndef OPENSSL_NO_BF
 # define OPENSSL_NO_BF
 #endif
 #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
@@ -22,9 +26,15 @@
 #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
@@ -37,11 +47,9 @@
 #ifndef OPENSSL_NO_SEED
 # define OPENSSL_NO_SEED
 #endif
-#ifndef OPENSSL_NO_TLSEXT
-# define OPENSSL_NO_TLSEXT
-#endif
 
 #endif /* OPENSSL_DOING_MAKEDEPEND */
+
 #ifndef OPENSSL_THREADS
 # define OPENSSL_THREADS
 #endif
@@ -60,6 +68,9 @@
 # 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
@@ -72,9 +83,15 @@
 # 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
@@ -87,13 +104,25 @@
 # if defined(OPENSSL_NO_SEED) && !defined(NO_SEED)
 #  define NO_SEED
 # endif
-# if defined(OPENSSL_NO_TLSEXT) && !defined(NO_TLSEXT)
-#  define NO_TLSEXT
-# endif
 #endif
 
 /* crypto/opensslconf.h.in */
 
+#ifdef OPENSSL_DOING_MAKEDEPEND
+
+/* Include any symbols here that have to be explicitly set to enable a feature
+ * that should be visible to makedepend.
+ *
+ * [Our "make depend" doesn't actually look at this, we use actual build settings
+ * instead; we want to make it easy to remove subdirectories with disabled algorithms.]
+ */
+
+#ifndef OPENSSL_FIPS
+#define OPENSSL_FIPS
+#endif
+
+#endif
+
 /* Generate 80386 code? */
 #undef I386_ONLY
 
diff --git a/crypto/opensslconf.h.in b/crypto/opensslconf.h.in
index cee83ac..1c77f03 100644
--- a/crypto/opensslconf.h.in
+++ b/crypto/opensslconf.h.in
@@ -1,5 +1,20 @@
 /* crypto/opensslconf.h.in */
 
+#ifdef OPENSSL_DOING_MAKEDEPEND
+
+/* Include any symbols here that have to be explicitly set to enable a feature
+ * that should be visible to makedepend.
+ *
+ * [Our "make depend" doesn't actually look at this, we use actual build settings
+ * instead; we want to make it easy to remove subdirectories with disabled algorithms.]
+ */
+
+#ifndef OPENSSL_FIPS
+#define OPENSSL_FIPS
+#endif
+
+#endif
+
 /* Generate 80386 code? */
 #undef I386_ONLY
 
diff --git a/crypto/opensslv.h b/crypto/opensslv.h
index b308894..c6207f7 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	0x0090808fL
+#define OPENSSL_VERSION_NUMBER	0x009080bfL
 #ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT	"OpenSSL 0.9.8h-fips 28 May 2008"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 0.9.8k-fips 25 Mar 2009"
 #else
-#define OPENSSL_VERSION_TEXT	"OpenSSL 0.9.8h 28 May 2008"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 0.9.8k 25 Mar 2009"
 #endif
 #define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
 
diff --git a/crypto/ossl_typ.h b/crypto/ossl_typ.h
index 345fb1d..0e7a380 100644
--- a/crypto/ossl_typ.h
+++ b/crypto/ossl_typ.h
@@ -100,6 +100,8 @@
 #undef X509_EXTENSIONS
 #undef X509_CERT_PAIR
 #undef PKCS7_ISSUER_AND_SERIAL
+#undef OCSP_REQUEST
+#undef OCSP_RESPONSE
 #endif
 
 #ifdef BIGNUM
@@ -140,6 +142,8 @@
 typedef struct X509_name_st X509_NAME;
 typedef struct x509_store_st X509_STORE;
 typedef struct x509_store_ctx_st X509_STORE_CTX;
+typedef struct ssl_st SSL;
+typedef struct ssl_ctx_st SSL_CTX;
 
 typedef struct v3_ext_ctx X509V3_CTX;
 typedef struct conf_st CONF;
diff --git a/crypto/pem/Makefile b/crypto/pem/Makefile
index 742194f..669f366 100644
--- a/crypto/pem/Makefile
+++ b/crypto/pem/Makefile
@@ -36,7 +36,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -83,36 +83,39 @@
 pem_all.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
 pem_all.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 pem_all.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-pem_all.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-pem_all.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-pem_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-pem_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
-pem_all.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
-pem_all.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-pem_all.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-pem_all.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-pem_all.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pem_all.c
+pem_all.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+pem_all.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pem_all.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pem_all.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pem_all.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+pem_all.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+pem_all.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+pem_all.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+pem_all.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+pem_all.o: ../cryptlib.h pem_all.c
 pem_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 pem_err.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 pem_err.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 pem_err.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 pem_err.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-pem_err.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-pem_err.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-pem_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-pem_err.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
-pem_err.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-pem_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-pem_err.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-pem_err.o: ../../include/openssl/x509_vfy.h pem_err.c
+pem_err.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+pem_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pem_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+pem_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
+pem_err.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
+pem_err.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+pem_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+pem_err.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+pem_err.o: pem_err.c
 pem_info.o: ../../e_os.h ../../include/openssl/asn1.h
 pem_info.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 pem_info.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
 pem_info.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 pem_info.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 pem_info.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-pem_info.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-pem_info.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pem_info.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+pem_info.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pem_info.o: ../../include/openssl/opensslconf.h
 pem_info.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 pem_info.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
 pem_info.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
@@ -126,54 +129,55 @@
 pem_lib.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
 pem_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 pem_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-pem_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-pem_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-pem_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-pem_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
-pem_lib.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs12.h
-pem_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
-pem_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-pem_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-pem_lib.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-pem_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-pem_lib.o: ../cryptlib.h pem_lib.c
+pem_lib.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+pem_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pem_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pem_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pem_lib.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+pem_lib.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+pem_lib.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+pem_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pem_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
+pem_lib.o: ../../include/openssl/ui_compat.h ../../include/openssl/x509.h
+pem_lib.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pem_lib.c
 pem_oth.o: ../../e_os.h ../../include/openssl/asn1.h
 pem_oth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 pem_oth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 pem_oth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 pem_oth.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-pem_oth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-pem_oth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-pem_oth.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-pem_oth.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
-pem_oth.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
-pem_oth.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-pem_oth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-pem_oth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-pem_oth.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pem_oth.c
+pem_oth.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+pem_oth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pem_oth.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pem_oth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pem_oth.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+pem_oth.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+pem_oth.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+pem_oth.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+pem_oth.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+pem_oth.o: ../cryptlib.h pem_oth.c
 pem_pk8.o: ../../e_os.h ../../include/openssl/asn1.h
 pem_pk8.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 pem_pk8.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 pem_pk8.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 pem_pk8.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-pem_pk8.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-pem_pk8.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-pem_pk8.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-pem_pk8.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
-pem_pk8.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs12.h
-pem_pk8.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
-pem_pk8.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-pem_pk8.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-pem_pk8.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-pem_pk8.o: ../cryptlib.h pem_pk8.c
+pem_pk8.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+pem_pk8.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pem_pk8.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pem_pk8.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pem_pk8.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+pem_pk8.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+pem_pk8.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+pem_pk8.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pem_pk8.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pem_pk8.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pem_pk8.c
 pem_pkey.o: ../../e_os.h ../../include/openssl/asn1.h
 pem_pkey.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 pem_pkey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 pem_pkey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 pem_pkey.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-pem_pkey.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-pem_pkey.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-pem_pkey.o: ../../include/openssl/opensslconf.h
+pem_pkey.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+pem_pkey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pem_pkey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 pem_pkey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 pem_pkey.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
 pem_pkey.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
@@ -186,9 +190,9 @@
 pem_seal.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 pem_seal.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 pem_seal.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-pem_seal.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-pem_seal.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-pem_seal.o: ../../include/openssl/opensslconf.h
+pem_seal.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+pem_seal.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pem_seal.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 pem_seal.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 pem_seal.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
 pem_seal.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
@@ -201,9 +205,9 @@
 pem_sign.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 pem_sign.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 pem_sign.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-pem_sign.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-pem_sign.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-pem_sign.o: ../../include/openssl/opensslconf.h
+pem_sign.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+pem_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pem_sign.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 pem_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 pem_sign.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
 pem_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
@@ -216,9 +220,9 @@
 pem_x509.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 pem_x509.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 pem_x509.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-pem_x509.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-pem_x509.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-pem_x509.o: ../../include/openssl/opensslconf.h
+pem_x509.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+pem_x509.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pem_x509.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 pem_x509.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 pem_x509.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
 pem_x509.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
@@ -230,9 +234,9 @@
 pem_xaux.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 pem_xaux.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 pem_xaux.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-pem_xaux.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-pem_xaux.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-pem_xaux.o: ../../include/openssl/opensslconf.h
+pem_xaux.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+pem_xaux.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pem_xaux.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 pem_xaux.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 pem_xaux.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
 pem_xaux.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
diff --git a/crypto/pem/pem.h b/crypto/pem/pem.h
index 670afa6..6c193f1 100644
--- a/crypto/pem/pem.h
+++ b/crypto/pem/pem.h
@@ -125,6 +125,7 @@
 #define PEM_STRING_DSA		"DSA PRIVATE KEY"
 #define PEM_STRING_DSA_PUBLIC	"DSA PUBLIC KEY"
 #define PEM_STRING_PKCS7	"PKCS7"
+#define PEM_STRING_PKCS7_SIGNED	"PKCS #7 SIGNED DATA"
 #define PEM_STRING_PKCS8	"ENCRYPTED PRIVATE KEY"
 #define PEM_STRING_PKCS8INF	"PRIVATE KEY"
 #define PEM_STRING_DHPARAMS	"DH PARAMETERS"
@@ -214,7 +215,9 @@
 
 #define IMPLEMENT_PEM_read_fp(name, type, str, asn1) /**/
 #define IMPLEMENT_PEM_write_fp(name, type, str, asn1) /**/
+#define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) /**/
 #define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) /**/
+#define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) /**/
 
 #else
 
@@ -354,6 +357,7 @@
 
 #define DECLARE_PEM_read_fp(name, type) /**/
 #define DECLARE_PEM_write_fp(name, type) /**/
+#define DECLARE_PEM_write_fp_const(name, type) /**/
 #define DECLARE_PEM_write_cb_fp(name, type) /**/
 
 #else
@@ -391,6 +395,7 @@
 
 #define DECLARE_PEM_read_bio(name, type) /**/
 #define DECLARE_PEM_write_bio(name, type) /**/
+#define DECLARE_PEM_write_bio_const(name, type) /**/
 #define DECLARE_PEM_write_cb_bio(name, type) /**/
 
 #endif
diff --git a/crypto/pem/pem_all.c b/crypto/pem/pem_all.c
index 66cbc7e..69dd19b 100644
--- a/crypto/pem/pem_all.c
+++ b/crypto/pem/pem_all.c
@@ -194,7 +194,49 @@
 
 #endif
 
+#ifdef OPENSSL_FIPS
+
+int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+	EVP_PKEY *k;
+	int ret;
+	k = EVP_PKEY_new();
+	if (!k)
+		return 0;
+	EVP_PKEY_set1_RSA(k, x);
+
+	ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
+	EVP_PKEY_free(k);
+	return ret;
+}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+	EVP_PKEY *k;
+	int ret;
+	k = EVP_PKEY_new();
+	if (!k)
+		return 0;
+
+	EVP_PKEY_set1_RSA(k, x);
+
+	ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
+	EVP_PKEY_free(k);
+	return ret;
+}
+#endif
+
+#else
+
 IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey)
+
+#endif
+
 IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, RSAPublicKey)
 IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, PEM_STRING_PUBLIC, RSA_PUBKEY)
 
@@ -224,7 +266,47 @@
 	return pkey_get_dsa(pktmp, dsa);
 }
 
+#ifdef OPENSSL_FIPS
+
+int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+	EVP_PKEY *k;
+	int ret;
+	k = EVP_PKEY_new();
+	if (!k)
+		return 0;
+	EVP_PKEY_set1_DSA(k, x);
+
+	ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
+	EVP_PKEY_free(k);
+	return ret;
+}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+	EVP_PKEY *k;
+	int ret;
+	k = EVP_PKEY_new();
+	if (!k)
+		return 0;
+	EVP_PKEY_set1_DSA(k, x);
+	ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
+	EVP_PKEY_free(k);
+	return ret;
+}
+#endif
+
+#else
+
 IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, DSAPrivateKey)
+
+#endif
+
 IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY)
 
 #ifndef OPENSSL_NO_FP_API
@@ -270,8 +352,49 @@
 
 IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, ECPKParameters)
 
+
+
+#ifdef OPENSSL_FIPS
+
+int PEM_write_bio_ECPrivateKey(BIO *bp, EC_KEY *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+	EVP_PKEY *k;
+	int ret;
+	k = EVP_PKEY_new();
+	if (!k)
+		return 0;
+	EVP_PKEY_set1_EC_KEY(k, x);
+
+	ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u);
+	EVP_PKEY_free(k);
+	return ret;
+}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_write_ECPrivateKey(FILE *fp, EC_KEY *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+{
+	EVP_PKEY *k;
+	int ret;
+	k = EVP_PKEY_new();
+	if (!k)
+		return 0;
+	EVP_PKEY_set1_EC_KEY(k, x);
+	ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u);
+	EVP_PKEY_free(k);
+	return ret;
+}
+#endif
+
+#else
+
 IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, ECPrivateKey)
 
+#endif
+
 IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY)
 
 #ifndef OPENSSL_NO_FP_API
@@ -301,8 +424,59 @@
  * (When reading, parameter PEM_STRING_EVP_PKEY is a wildcard for anything
  * appropriate.)
  */
+
+#ifdef OPENSSL_FIPS
+
+static const char *pkey_str(EVP_PKEY *x)
+	{
+	switch (x->type)
+		{
+		case EVP_PKEY_RSA:
+		return PEM_STRING_RSA;
+
+		case EVP_PKEY_DSA:
+		return PEM_STRING_DSA;
+
+		case EVP_PKEY_EC:
+		return PEM_STRING_ECPRIVATEKEY;
+
+		default:
+		return NULL;
+		}
+	}
+
+
+int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+	{
+		if (FIPS_mode())
+			return PEM_write_bio_PKCS8PrivateKey(bp, x, enc,
+						(char *)kstr, klen, cb, u);
+		else
+                	return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey,
+			pkey_str(x), bp,(char *)x,enc,kstr,klen,cb,u);
+	}
+
+#ifndef OPENSSL_NO_FP_API
+int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+                                               unsigned char *kstr, int klen,
+                                               pem_password_cb *cb, void *u)
+	{
+		if (FIPS_mode())
+			return PEM_write_PKCS8PrivateKey(fp, x, enc,
+						(char *)kstr, klen, cb, u);
+		else
+                	return PEM_ASN1_write((i2d_of_void *)i2d_PrivateKey,
+			pkey_str(x), fp,(char *)x,enc,kstr,klen,cb,u);
+	}
+#endif
+
+#else
 IMPLEMENT_PEM_write_cb(PrivateKey, EVP_PKEY, ((x->type == EVP_PKEY_DSA)?PEM_STRING_DSA:\
 			(x->type == EVP_PKEY_RSA)?PEM_STRING_RSA:PEM_STRING_ECPRIVATEKEY), PrivateKey)
 
+#endif
+
 IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)
 
diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c
index 9bae4c8..cbafefe 100644
--- a/crypto/pem/pem_lib.c
+++ b/crypto/pem/pem_lib.c
@@ -216,6 +216,9 @@
 	if(!strcmp(nm, PEM_STRING_X509) &&
 		!strcmp(name, PEM_STRING_PKCS7)) return 1;
 
+	if(!strcmp(nm, PEM_STRING_PKCS7_SIGNED) &&
+		!strcmp(name, PEM_STRING_PKCS7)) return 1;
+
 	return 0;
 }
 
diff --git a/crypto/pem/pem_x509.c b/crypto/pem/pem_x509.c
index 19f88d8..3f709f1 100644
--- a/crypto/pem/pem_x509.c
+++ b/crypto/pem/pem_x509.c
@@ -1,5 +1,5 @@
 /* pem_x509.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2001.
  */
 /* ====================================================================
diff --git a/crypto/pem/pem_xaux.c b/crypto/pem/pem_xaux.c
index 63ce660..7cc7491 100644
--- a/crypto/pem/pem_xaux.c
+++ b/crypto/pem/pem_xaux.c
@@ -1,5 +1,5 @@
 /* pem_xaux.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2001.
  */
 /* ====================================================================
diff --git a/crypto/pkcs12/Makefile b/crypto/pkcs12/Makefile
index 3a7498f..eed226b 100644
--- a/crypto/pkcs12/Makefile
+++ b/crypto/pkcs12/Makefile
@@ -39,7 +39,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -85,36 +85,37 @@
 p12_add.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 p12_add.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 p12_add.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-p12_add.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-p12_add.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-p12_add.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-p12_add.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
-p12_add.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-p12_add.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-p12_add.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-p12_add.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_add.c
+p12_add.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+p12_add.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p12_add.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p12_add.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p12_add.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+p12_add.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p12_add.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p12_add.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p12_add.o: ../cryptlib.h p12_add.c
 p12_asn.o: ../../e_os.h ../../include/openssl/asn1.h
 p12_asn.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 p12_asn.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 p12_asn.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 p12_asn.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 p12_asn.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-p12_asn.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-p12_asn.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-p12_asn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-p12_asn.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
-p12_asn.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-p12_asn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-p12_asn.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-p12_asn.o: ../cryptlib.h p12_asn.c
+p12_asn.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+p12_asn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p12_asn.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+p12_asn.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
+p12_asn.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+p12_asn.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+p12_asn.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+p12_asn.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_asn.c
 p12_attr.o: ../../e_os.h ../../include/openssl/asn1.h
 p12_attr.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 p12_attr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 p12_attr.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 p12_attr.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-p12_attr.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-p12_attr.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-p12_attr.o: ../../include/openssl/opensslconf.h
+p12_attr.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+p12_attr.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p12_attr.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 p12_attr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 p12_attr.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
 p12_attr.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
@@ -126,9 +127,9 @@
 p12_crpt.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 p12_crpt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 p12_crpt.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-p12_crpt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-p12_crpt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-p12_crpt.o: ../../include/openssl/opensslconf.h
+p12_crpt.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+p12_crpt.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p12_crpt.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 p12_crpt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 p12_crpt.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
 p12_crpt.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
@@ -140,22 +141,23 @@
 p12_crt.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 p12_crt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 p12_crt.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-p12_crt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-p12_crt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-p12_crt.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-p12_crt.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
-p12_crt.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-p12_crt.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-p12_crt.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-p12_crt.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_crt.c
+p12_crt.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+p12_crt.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p12_crt.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p12_crt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p12_crt.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+p12_crt.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p12_crt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p12_crt.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p12_crt.o: ../cryptlib.h p12_crt.c
 p12_decr.o: ../../e_os.h ../../include/openssl/asn1.h
 p12_decr.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 p12_decr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 p12_decr.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 p12_decr.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-p12_decr.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-p12_decr.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-p12_decr.o: ../../include/openssl/opensslconf.h
+p12_decr.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+p12_decr.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p12_decr.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 p12_decr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 p12_decr.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
 p12_decr.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
@@ -167,9 +169,9 @@
 p12_init.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 p12_init.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 p12_init.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-p12_init.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-p12_init.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-p12_init.o: ../../include/openssl/opensslconf.h
+p12_init.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+p12_init.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p12_init.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 p12_init.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 p12_init.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
 p12_init.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
@@ -182,22 +184,22 @@
 p12_key.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 p12_key.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 p12_key.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-p12_key.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-p12_key.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-p12_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-p12_key.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
-p12_key.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-p12_key.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-p12_key.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-p12_key.o: ../cryptlib.h p12_key.c
+p12_key.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+p12_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p12_key.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+p12_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
+p12_key.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+p12_key.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+p12_key.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+p12_key.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_key.c
 p12_kiss.o: ../../e_os.h ../../include/openssl/asn1.h
 p12_kiss.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 p12_kiss.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 p12_kiss.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 p12_kiss.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-p12_kiss.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-p12_kiss.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-p12_kiss.o: ../../include/openssl/opensslconf.h
+p12_kiss.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+p12_kiss.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p12_kiss.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 p12_kiss.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 p12_kiss.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
 p12_kiss.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
@@ -209,9 +211,10 @@
 p12_mutl.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 p12_mutl.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 p12_mutl.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-p12_mutl.o: ../../include/openssl/evp.h ../../include/openssl/hmac.h
-p12_mutl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-p12_mutl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p12_mutl.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+p12_mutl.o: ../../include/openssl/hmac.h ../../include/openssl/lhash.h
+p12_mutl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p12_mutl.o: ../../include/openssl/opensslconf.h
 p12_mutl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 p12_mutl.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
 p12_mutl.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
@@ -223,8 +226,9 @@
 p12_npas.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 p12_npas.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 p12_npas.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-p12_npas.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-p12_npas.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p12_npas.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+p12_npas.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+p12_npas.o: ../../include/openssl/opensslconf.h
 p12_npas.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 p12_npas.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
 p12_npas.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
@@ -237,50 +241,53 @@
 p12_p8d.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 p12_p8d.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 p12_p8d.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-p12_p8d.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-p12_p8d.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-p12_p8d.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-p12_p8d.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
-p12_p8d.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-p12_p8d.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-p12_p8d.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-p12_p8d.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_p8d.c
+p12_p8d.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+p12_p8d.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p12_p8d.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p12_p8d.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p12_p8d.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+p12_p8d.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p12_p8d.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p12_p8d.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p12_p8d.o: ../cryptlib.h p12_p8d.c
 p12_p8e.o: ../../e_os.h ../../include/openssl/asn1.h
 p12_p8e.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 p12_p8e.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 p12_p8e.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 p12_p8e.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-p12_p8e.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-p12_p8e.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-p12_p8e.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-p12_p8e.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
-p12_p8e.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-p12_p8e.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-p12_p8e.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-p12_p8e.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_p8e.c
+p12_p8e.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+p12_p8e.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p12_p8e.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p12_p8e.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p12_p8e.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+p12_p8e.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p12_p8e.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p12_p8e.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p12_p8e.o: ../cryptlib.h p12_p8e.c
 p12_utl.o: ../../e_os.h ../../include/openssl/asn1.h
 p12_utl.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 p12_utl.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 p12_utl.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 p12_utl.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-p12_utl.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-p12_utl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-p12_utl.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-p12_utl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
-p12_utl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-p12_utl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-p12_utl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-p12_utl.o: ../../include/openssl/x509_vfy.h ../cryptlib.h p12_utl.c
+p12_utl.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+p12_utl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+p12_utl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+p12_utl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+p12_utl.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
+p12_utl.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+p12_utl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+p12_utl.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+p12_utl.o: ../cryptlib.h p12_utl.c
 pk12err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 pk12err.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 pk12err.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 pk12err.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 pk12err.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-pk12err.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-pk12err.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-pk12err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-pk12err.o: ../../include/openssl/pkcs12.h ../../include/openssl/pkcs7.h
-pk12err.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-pk12err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-pk12err.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-pk12err.o: pk12err.c
+pk12err.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+pk12err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pk12err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+pk12err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs12.h
+pk12err.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+pk12err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pk12err.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pk12err.o: ../../include/openssl/x509_vfy.h pk12err.c
diff --git a/crypto/pkcs12/p12_add.c b/crypto/pkcs12/p12_add.c
index 41bdc00..1f3e378 100644
--- a/crypto/pkcs12/p12_add.c
+++ b/crypto/pkcs12/p12_add.c
@@ -1,5 +1,5 @@
 /* p12_add.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/pkcs12/p12_asn.c b/crypto/pkcs12/p12_asn.c
index a3739fe..6e27633 100644
--- a/crypto/pkcs12/p12_asn.c
+++ b/crypto/pkcs12/p12_asn.c
@@ -1,5 +1,5 @@
 /* p12_asn.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/pkcs12/p12_attr.c b/crypto/pkcs12/p12_attr.c
index 026cf38..68d6c5a 100644
--- a/crypto/pkcs12/p12_attr.c
+++ b/crypto/pkcs12/p12_attr.c
@@ -1,5 +1,5 @@
 /* p12_attr.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/pkcs12/p12_crpt.c b/crypto/pkcs12/p12_crpt.c
index 3ad33c4..f8b952e 100644
--- a/crypto/pkcs12/p12_crpt.c
+++ b/crypto/pkcs12/p12_crpt.c
@@ -1,5 +1,5 @@
 /* p12_crpt.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/pkcs12/p12_crt.c b/crypto/pkcs12/p12_crt.c
index dbafda1..9522342 100644
--- a/crypto/pkcs12/p12_crt.c
+++ b/crypto/pkcs12/p12_crt.c
@@ -1,5 +1,5 @@
 /* p12_crt.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project.
  */
 /* ====================================================================
@@ -59,10 +59,27 @@
 #include <stdio.h>
 #include "cryptlib.h"
 #include <openssl/pkcs12.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 
 
 static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag);
 
+static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid)
+	{
+	int idx;
+	X509_ATTRIBUTE *attr;
+	idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1);
+	if (idx < 0)
+		return 1;
+	attr = EVP_PKEY_get_attr(pkey, idx);
+	if (!X509at_add1_attr(&bag->attrib, attr))
+		return 0;
+	return 1;
+	}
+
 PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
 	     STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter,
 	     int keytype)
@@ -77,7 +94,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)
@@ -122,20 +146,15 @@
 
 	if (pkey)
 		{
-		int cspidx;
 		bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass);
 
 		if (!bag)
 			goto err;
 
-		cspidx = EVP_PKEY_get_attr_by_NID(pkey, NID_ms_csp_name, -1);
-		if (cspidx >= 0)
-			{
-			X509_ATTRIBUTE *cspattr;
-			cspattr = EVP_PKEY_get_attr(pkey, cspidx);
-			if (!X509at_add1_attr(&bag->attrib, cspattr))
-				goto err;
-			}
+		if (!copy_bag_attr(bag, pkey, NID_ms_csp_name))
+			goto err;
+		if (!copy_bag_attr(bag, pkey, NID_LocalKeySet))
+			goto err;
 
 		if(name && !PKCS12_add_friendlyname(bag, name, -1))
 			goto err;
@@ -151,6 +170,9 @@
 
 	p12 = PKCS12_add_safes(safes, 0);
 
+	if (!p12)
+		goto err;
+
 	sk_PKCS7_pop_free(safes, PKCS7_free);
 
 	safes = NULL;
diff --git a/crypto/pkcs12/p12_decr.c b/crypto/pkcs12/p12_decr.c
index 74c961a..ba77dbb 100644
--- a/crypto/pkcs12/p12_decr.c
+++ b/crypto/pkcs12/p12_decr.c
@@ -1,5 +1,5 @@
 /* p12_decr.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/pkcs12/p12_init.c b/crypto/pkcs12/p12_init.c
index 6bdc132..d4d84b0 100644
--- a/crypto/pkcs12/p12_init.c
+++ b/crypto/pkcs12/p12_init.c
@@ -1,5 +1,5 @@
 /* p12_init.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/pkcs12/p12_key.c b/crypto/pkcs12/p12_key.c
index 18e72d0..9e57eee 100644
--- a/crypto/pkcs12/p12_key.c
+++ b/crypto/pkcs12/p12_key.c
@@ -1,5 +1,5 @@
 /* p12_key.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/pkcs12/p12_kiss.c b/crypto/pkcs12/p12_kiss.c
index c2ee2cc..5c4c6ec 100644
--- a/crypto/pkcs12/p12_kiss.c
+++ b/crypto/pkcs12/p12_kiss.c
@@ -1,5 +1,5 @@
 /* p12_kiss.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/pkcs12/p12_mutl.c b/crypto/pkcs12/p12_mutl.c
index c408cc8..70bfef6 100644
--- a/crypto/pkcs12/p12_mutl.c
+++ b/crypto/pkcs12/p12_mutl.c
@@ -1,5 +1,5 @@
 /* p12_mutl.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/pkcs12/p12_npas.c b/crypto/pkcs12/p12_npas.c
index 48eacc5..47e5e9c 100644
--- a/crypto/pkcs12/p12_npas.c
+++ b/crypto/pkcs12/p12_npas.c
@@ -1,5 +1,5 @@
 /* p12_npas.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/pkcs12/p12_p8d.c b/crypto/pkcs12/p12_p8d.c
index 3c6f377..deba81e 100644
--- a/crypto/pkcs12/p12_p8d.c
+++ b/crypto/pkcs12/p12_p8d.c
@@ -1,5 +1,5 @@
 /* p12_p8d.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2001.
  */
 /* ====================================================================
diff --git a/crypto/pkcs12/p12_p8e.c b/crypto/pkcs12/p12_p8e.c
index 3d47956..bf20a77 100644
--- a/crypto/pkcs12/p12_p8e.c
+++ b/crypto/pkcs12/p12_p8e.c
@@ -1,5 +1,5 @@
 /* p12_p8e.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2001.
  */
 /* ====================================================================
diff --git a/crypto/pkcs12/p12_utl.c b/crypto/pkcs12/p12_utl.c
index 243ec76..ca30ac4 100644
--- a/crypto/pkcs12/p12_utl.c
+++ b/crypto/pkcs12/p12_utl.c
@@ -1,5 +1,5 @@
 /* p12_utl.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/pkcs12/pkcs12.h b/crypto/pkcs12/pkcs12.h
index a2d7e35..4bee605 100644
--- a/crypto/pkcs12/pkcs12.h
+++ b/crypto/pkcs12/pkcs12.h
@@ -1,5 +1,5 @@
 /* pkcs12.h */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/pkcs7/Makefile b/crypto/pkcs7/Makefile
index 3f7e88b..790d8ed 100644
--- a/crypto/pkcs7/Makefile
+++ b/crypto/pkcs7/Makefile
@@ -54,7 +54,7 @@
 	$(CC) $(CFLAGS) -o verify verify.o $(PEX_LIBS) example.o $(LIB) $(EX_LIBS)
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -101,8 +101,9 @@
 pk7_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 pk7_asn1.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 pk7_asn1.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-pk7_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-pk7_asn1.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pk7_asn1.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+pk7_asn1.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pk7_asn1.o: ../../include/openssl/opensslconf.h
 pk7_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 pk7_asn1.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 pk7_asn1.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -113,8 +114,9 @@
 pk7_attr.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 pk7_attr.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 pk7_attr.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-pk7_attr.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-pk7_attr.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pk7_attr.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+pk7_attr.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pk7_attr.o: ../../include/openssl/opensslconf.h
 pk7_attr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 pk7_attr.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
 pk7_attr.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
@@ -127,8 +129,9 @@
 pk7_doit.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 pk7_doit.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 pk7_doit.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-pk7_doit.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-pk7_doit.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pk7_doit.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+pk7_doit.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pk7_doit.o: ../../include/openssl/opensslconf.h
 pk7_doit.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 pk7_doit.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
 pk7_doit.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
@@ -140,22 +143,22 @@
 pk7_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 pk7_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 pk7_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-pk7_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-pk7_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-pk7_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-pk7_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-pk7_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-pk7_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-pk7_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-pk7_lib.o: ../cryptlib.h pk7_lib.c
+pk7_lib.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+pk7_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pk7_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pk7_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+pk7_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+pk7_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+pk7_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+pk7_lib.o: ../../include/openssl/x509_vfy.h ../cryptlib.h pk7_lib.c
 pk7_mime.o: ../../e_os.h ../../include/openssl/asn1.h
 pk7_mime.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 pk7_mime.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 pk7_mime.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 pk7_mime.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-pk7_mime.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-pk7_mime.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-pk7_mime.o: ../../include/openssl/opensslconf.h
+pk7_mime.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+pk7_mime.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+pk7_mime.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 pk7_mime.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 pk7_mime.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
 pk7_mime.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
@@ -168,8 +171,8 @@
 pk7_smime.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 pk7_smime.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 pk7_smime.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-pk7_smime.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-pk7_smime.o: ../../include/openssl/objects.h
+pk7_smime.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+pk7_smime.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 pk7_smime.o: ../../include/openssl/opensslconf.h
 pk7_smime.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 pk7_smime.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
diff --git a/crypto/pkcs7/pk7_asn1.c b/crypto/pkcs7/pk7_asn1.c
index 77931fe..1f70d31 100644
--- a/crypto/pkcs7/pk7_asn1.c
+++ b/crypto/pkcs7/pk7_asn1.c
@@ -1,5 +1,5 @@
 /* pk7_asn.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/crypto/pkcs7/pk7_attr.c b/crypto/pkcs7/pk7_attr.c
index 735c880..d549717 100644
--- a/crypto/pkcs7/pk7_attr.c
+++ b/crypto/pkcs7/pk7_attr.c
@@ -1,5 +1,5 @@
 /* pk7_attr.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2001.
  */
 /* ====================================================================
diff --git a/crypto/pkcs7/pk7_mime.c b/crypto/pkcs7/pk7_mime.c
index 17b6899..bf19036 100644
--- a/crypto/pkcs7/pk7_mime.c
+++ b/crypto/pkcs7/pk7_mime.c
@@ -1,5 +1,5 @@
 /* pk7_mime.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project.
  */
 /* ====================================================================
diff --git a/crypto/pkcs7/pk7_smime.c b/crypto/pkcs7/pk7_smime.c
index 5c6b0fe..fd18ec3 100644
--- a/crypto/pkcs7/pk7_smime.c
+++ b/crypto/pkcs7/pk7_smime.c
@@ -1,5 +1,5 @@
 /* pk7_smime.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project.
  */
 /* ====================================================================
@@ -229,8 +229,7 @@
 				sk_X509_free(signers);
 				return 0;
 				}
-			X509_STORE_CTX_set_purpose(&cert_ctx,
-						X509_PURPOSE_SMIME_SIGN);
+			X509_STORE_CTX_set_default(&cert_ctx, "smime_sign");
 		} else if(!X509_STORE_CTX_init (&cert_ctx, store, signer, NULL)) {
 			PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_X509_LIB);
 			sk_X509_free(signers);
@@ -282,6 +281,7 @@
 			PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_MALLOC_FAILURE);
 			goto err;
 		}
+		BIO_set_mem_eof_return(tmpout, 0);
 	} else tmpout = out;
 
 	/* We now have to 'read' from p7bio to calculate digests etc. */
diff --git a/crypto/ppccpuid.pl b/crypto/ppccpuid.pl
new file mode 100755
index 0000000..fe44ff0
--- /dev/null
+++ b/crypto/ppccpuid.pl
@@ -0,0 +1,94 @@
+#!/usr/bin/env perl
+
+$flavour = shift;
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}perlasm/ppc-xlate.pl" and -f $xlate) or
+die "can't locate ppc-xlate.pl";
+
+open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!";
+
+if ($flavour=~/64/) {
+    $CMPLI="cmpldi";
+    $SHRLI="srdi";
+    $SIGNX="extsw";
+} else {
+    $CMPLI="cmplwi";
+    $SHRLI="srwi";
+    $SIGNX="mr";
+}
+
+$code=<<___;
+.machine	"any"
+.text
+
+.globl	.OPENSSL_cpuid_setup
+.align	4
+.OPENSSL_cpuid_setup:
+	blr
+
+.globl	.OPENSSL_wipe_cpu
+.align	4
+.OPENSSL_wipe_cpu:
+	xor	r0,r0,r0
+	mr	r3,r1
+	xor	r4,r4,r4
+	xor	r5,r5,r5
+	xor	r6,r6,r6
+	xor	r7,r7,r7
+	xor	r8,r8,r8
+	xor	r9,r9,r9
+	xor	r10,r10,r10
+	xor	r11,r11,r11
+	xor	r12,r12,r12
+	blr
+
+.globl	.OPENSSL_atomic_add
+.align	4
+.OPENSSL_atomic_add:
+Loop:	lwarx	r5,0,r3
+	add	r0,r4,r5
+	stwcx.	r0,0,r3
+	bne-	Loop
+	$SIGNX	r3,r0
+	blr
+
+.globl	.OPENSSL_rdtsc
+.align	4
+.OPENSSL_rdtsc:
+	mftb	r3
+	mftbu	r4
+	blr
+
+.globl	.OPENSSL_cleanse
+.align	4
+.OPENSSL_cleanse:
+	$CMPLI	r4,7
+	li	r0,0
+	bge	Lot
+Little:	mtctr	r4
+	stb	r0,0(r3)
+	addi	r3,r3,1
+	bdnz-	\$-8
+	blr
+Lot:	andi.	r5,r3,3
+	beq	Laligned
+	stb	r0,0(r3)
+	subi	r4,r4,1
+	addi	r3,r3,1
+	b	Lot
+Laligned:
+	$SHRLI	r5,r4,2
+	mtctr	r5
+	stw	r0,0(r3)
+	addi	r3,r3,4
+	bdnz-	\$-8
+	andi.	r4,r4,3
+	bne	Little
+	blr
+___
+
+$code =~ s/\`([^\`]*)\`/eval $1/gem;
+print $code;
+close STDOUT;
diff --git a/crypto/pqueue/Makefile b/crypto/pqueue/Makefile
index d0c39d2..36bfc34 100644
--- a/crypto/pqueue/Makefile
+++ b/crypto/pqueue/Makefile
@@ -33,7 +33,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
diff --git a/crypto/pqueue/pq_compat.h b/crypto/pqueue/pq_compat.h
index fd36578..7b2c327 100644
--- a/crypto/pqueue/pq_compat.h
+++ b/crypto/pqueue/pq_compat.h
@@ -57,6 +57,9 @@
  *
  */
 
+#ifndef HEADER_PQ_COMPAT_H
+#define HEADER_PQ_COMPAT_H
+
 #include <openssl/opensslconf.h>
 #include <openssl/bn.h>
 
@@ -145,3 +148,5 @@
                                               *(x) |= mask; \
                                           } while(0)
 #endif /* OPENSSL_SYS_VMS */
+
+#endif
diff --git a/crypto/rand/Makefile b/crypto/rand/Makefile
index 3c1ab5b..3079430 100644
--- a/crypto/rand/Makefile
+++ b/crypto/rand/Makefile
@@ -17,9 +17,9 @@
 APPS=
 
 LIB=$(TOP)/libcrypto.a
-LIBSRC=md_rand.c randfile.c rand_lib.c rand_err.c rand_egd.c \
+LIBSRC=md_rand.c randfile.c rand_lib.c rand_eng.c rand_err.c rand_egd.c \
 	rand_win.c rand_unix.c rand_os2.c rand_nw.c
-LIBOBJ=md_rand.o randfile.o rand_lib.o rand_err.o rand_egd.o \
+LIBOBJ=md_rand.o randfile.o rand_lib.o rand_eng.o rand_err.o rand_egd.o \
 	rand_win.o rand_unix.o rand_os2.o rand_nw.o
 
 SRC= $(LIBSRC)
@@ -35,7 +35,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -79,17 +79,34 @@
 md_rand.o: ../../e_os.h ../../include/openssl/asn1.h
 md_rand.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
 md_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-md_rand.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-md_rand.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-md_rand.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-md_rand.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-md_rand.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-md_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-md_rand.o: md_rand.c rand_lcl.h
+md_rand.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+md_rand.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+md_rand.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+md_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+md_rand.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+md_rand.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+md_rand.o: ../../include/openssl/symhacks.h md_rand.c rand_lcl.h
 rand_egd.o: ../../include/openssl/buffer.h ../../include/openssl/e_os2.h
 rand_egd.o: ../../include/openssl/opensslconf.h
 rand_egd.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
 rand_egd.o: rand_egd.c
+rand_eng.o: ../../e_os.h ../../include/openssl/asn1.h
+rand_eng.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+rand_eng.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+rand_eng.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
+rand_eng.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+rand_eng.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+rand_eng.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+rand_eng.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+rand_eng.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rand_eng.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rand_eng.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rand_eng.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+rand_eng.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+rand_eng.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rand_eng.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+rand_eng.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+rand_eng.o: ../cryptlib.h rand_eng.c rand_lcl.h
 rand_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
 rand_err.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
 rand_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
@@ -97,31 +114,41 @@
 rand_err.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
 rand_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 rand_err.o: rand_err.c
-rand_lib.o: ../../e_os.h ../../include/openssl/bio.h
-rand_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rand_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-rand_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-rand_lib.o: ../../include/openssl/opensslconf.h
+rand_lib.o: ../../e_os.h ../../include/openssl/asn1.h
+rand_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+rand_lib.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
+rand_lib.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
+rand_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+rand_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
+rand_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
+rand_lib.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+rand_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rand_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 rand_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rand_lib.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+rand_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+rand_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 rand_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rand_lib.o: ../cryptlib.h rand_lib.c
+rand_lib.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+rand_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+rand_lib.o: ../cryptlib.h rand_lcl.h rand_lib.c
 rand_nw.o: ../../e_os.h ../../include/openssl/asn1.h
 rand_nw.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 rand_nw.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 rand_nw.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-rand_nw.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-rand_nw.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-rand_nw.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-rand_nw.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-rand_nw.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-rand_nw.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h rand_nw.c
+rand_nw.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+rand_nw.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+rand_nw.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+rand_nw.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+rand_nw.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+rand_nw.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rand_nw.o: ../cryptlib.h rand_lcl.h rand_nw.c
 rand_os2.o: ../../e_os.h ../../include/openssl/asn1.h
 rand_os2.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 rand_os2.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 rand_os2.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-rand_os2.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-rand_os2.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rand_os2.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+rand_os2.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+rand_os2.o: ../../include/openssl/opensslconf.h
 rand_os2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 rand_os2.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
 rand_os2.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -131,8 +158,8 @@
 rand_unix.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 rand_unix.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 rand_unix.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-rand_unix.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-rand_unix.o: ../../include/openssl/objects.h
+rand_unix.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+rand_unix.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 rand_unix.o: ../../include/openssl/opensslconf.h
 rand_unix.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 rand_unix.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
@@ -143,8 +170,9 @@
 rand_win.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 rand_win.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 rand_win.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-rand_win.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-rand_win.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rand_win.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+rand_win.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+rand_win.o: ../../include/openssl/opensslconf.h
 rand_win.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 rand_win.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
 rand_win.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
diff --git a/crypto/rand/md_rand.c b/crypto/rand/md_rand.c
index 9783d0c..0f8dd3e 100644
--- a/crypto/rand/md_rand.c
+++ b/crypto/rand/md_rand.c
@@ -126,6 +126,10 @@
 
 #include <openssl/crypto.h>
 #include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 
 #ifdef BN_DEBUG
 # define PREDICT
@@ -332,6 +336,14 @@
 #endif
 	int do_stir_pool = 0;
 
+#ifdef OPENSSL_FIPS
+	if(FIPS_mode())
+	    {
+	    FIPSerr(FIPS_F_SSLEAY_RAND_BYTES,FIPS_R_NON_FIPS_METHOD);
+	    return 0;
+	    }
+#endif
+
 #ifdef PREDICT
 	if (rand_predictable)
 		{
diff --git a/crypto/rand/rand.h b/crypto/rand/rand.h
index ac6c021..ea89153 100644
--- a/crypto/rand/rand.h
+++ b/crypto/rand/rand.h
@@ -72,7 +72,7 @@
 #endif
 
 #if defined(OPENSSL_FIPS)
-#define FIPS_RAND_SIZE_T size_t
+#define FIPS_RAND_SIZE_T int
 #endif
 
 /* Already defined in ossl_typ.h */
@@ -111,6 +111,15 @@
 int RAND_egd(const char *path);
 int RAND_egd_bytes(const char *path,int bytes);
 int RAND_poll(void);
+#ifndef OPENSSL_NO_ENGINE
+#ifdef OPENSSL_FIPS
+void int_RAND_init_engine_callbacks(void);
+void int_RAND_set_callbacks(
+	int (*set_rand_func)(const RAND_METHOD *meth,
+						const RAND_METHOD **pmeth),
+	const RAND_METHOD *(*get_rand_func)(const RAND_METHOD **pmeth));
+#endif
+#endif
 
 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
 
@@ -128,11 +137,29 @@
 /* Error codes for the RAND functions. */
 
 /* Function codes. */
+#define RAND_F_ENG_RAND_GET_RAND_METHOD			 108
+#define RAND_F_FIPS_RAND				 103
+#define RAND_F_FIPS_RAND_BYTES				 102
+#define RAND_F_FIPS_RAND_GET_RAND_METHOD		 109
+#define RAND_F_FIPS_RAND_SET_DT				 106
+#define RAND_F_FIPS_SET_DT				 104
+#define RAND_F_FIPS_SET_PRNG_SEED			 107
+#define RAND_F_FIPS_SET_TEST_MODE			 105
 #define RAND_F_RAND_GET_RAND_METHOD			 101
 #define RAND_F_SSLEAY_RAND_BYTES			 100
 
 /* Reason codes. */
+#define RAND_R_NON_FIPS_METHOD				 105
+#define RAND_R_NOT_IN_TEST_MODE				 106
+#define RAND_R_NO_KEY_SET				 107
+#define RAND_R_PRNG_ASKING_FOR_TOO_MUCH			 101
+#define RAND_R_PRNG_ERROR				 108
+#define RAND_R_PRNG_KEYED				 109
+#define RAND_R_PRNG_NOT_REKEYED				 102
+#define RAND_R_PRNG_NOT_RESEEDED			 103
 #define RAND_R_PRNG_NOT_SEEDED				 100
+#define RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY		 110
+#define RAND_R_PRNG_STUCK				 104
 
 #ifdef  __cplusplus
 }
diff --git a/crypto/rand/rand_eng.c b/crypto/rand/rand_eng.c
new file mode 100644
index 0000000..1669cef
--- /dev/null
+++ b/crypto/rand/rand_eng.c
@@ -0,0 +1,152 @@
+/* crypto/rand/rand_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include "cryptlib.h"
+#include "rand_lcl.h"
+#include <openssl/rand.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#include <openssl/fips_rand.h>
+#endif
+
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+#if defined(OPENSSL_FIPS) && !defined(OPENSSL_NO_ENGINE)
+
+/* non-NULL if default_RAND_meth is ENGINE-provided */
+static ENGINE *funct_ref =NULL;
+
+int eng_RAND_set_rand_method(const RAND_METHOD *meth, const RAND_METHOD **pmeth)
+	{
+	if(funct_ref)
+		{
+		ENGINE_finish(funct_ref);
+		funct_ref = NULL;
+		}
+	*pmeth = meth;
+	return 1;
+	}
+
+const RAND_METHOD *eng_RAND_get_rand_method(const RAND_METHOD **pmeth)
+	{
+	if (!*pmeth)
+		{
+		ENGINE *e = ENGINE_get_default_RAND();
+		if(e)
+			{
+			*pmeth = ENGINE_get_RAND(e);
+			if(!*pmeth)
+				{
+				ENGINE_finish(e);
+				e = NULL;
+				}
+			}
+		if(e)
+			funct_ref = e;
+		else
+			if(FIPS_mode())
+				*pmeth=FIPS_rand_method();
+			else
+			*pmeth = RAND_SSLeay();
+		}
+
+	if(FIPS_mode()
+		&& *pmeth != FIPS_rand_check())
+	    {
+	    RANDerr(RAND_F_ENG_RAND_GET_RAND_METHOD,RAND_R_NON_FIPS_METHOD);
+	    return 0;
+	    }
+
+	return *pmeth;
+	}
+
+int RAND_set_rand_engine(ENGINE *engine)
+	{
+	const RAND_METHOD *tmp_meth = NULL;
+	if(engine)
+		{
+		if(!ENGINE_init(engine))
+			return 0;
+		tmp_meth = ENGINE_get_RAND(engine);
+		if(!tmp_meth)
+			{
+			ENGINE_finish(engine);
+			return 0;
+			}
+		}
+	/* This function releases any prior ENGINE so call it first */
+	RAND_set_rand_method(tmp_meth);
+	funct_ref = engine;
+	return 1;
+	}
+
+void int_RAND_init_engine_callbacks(void)
+	{
+	static int done = 0;
+	if (done)
+		return;
+	int_RAND_set_callbacks(eng_RAND_set_rand_method,
+				 eng_RAND_get_rand_method);
+	done = 1;
+	}
+
+#endif
diff --git a/crypto/rand/rand_err.c b/crypto/rand/rand_err.c
index 386934d..829fb44 100644
--- a/crypto/rand/rand_err.c
+++ b/crypto/rand/rand_err.c
@@ -1,6 +1,6 @@
 /* crypto/rand/rand_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2007 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
@@ -70,6 +70,14 @@
 
 static ERR_STRING_DATA RAND_str_functs[]=
 	{
+{ERR_FUNC(RAND_F_ENG_RAND_GET_RAND_METHOD),	"ENG_RAND_GET_RAND_METHOD"},
+{ERR_FUNC(RAND_F_FIPS_RAND),	"FIPS_RAND"},
+{ERR_FUNC(RAND_F_FIPS_RAND_BYTES),	"FIPS_RAND_BYTES"},
+{ERR_FUNC(RAND_F_FIPS_RAND_GET_RAND_METHOD),	"FIPS_RAND_GET_RAND_METHOD"},
+{ERR_FUNC(RAND_F_FIPS_RAND_SET_DT),	"FIPS_RAND_SET_DT"},
+{ERR_FUNC(RAND_F_FIPS_SET_DT),	"FIPS_SET_DT"},
+{ERR_FUNC(RAND_F_FIPS_SET_PRNG_SEED),	"FIPS_SET_PRNG_SEED"},
+{ERR_FUNC(RAND_F_FIPS_SET_TEST_MODE),	"FIPS_SET_TEST_MODE"},
 {ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD),	"RAND_get_rand_method"},
 {ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES),	"SSLEAY_RAND_BYTES"},
 {0,NULL}
@@ -77,7 +85,17 @@
 
 static ERR_STRING_DATA RAND_str_reasons[]=
 	{
+{ERR_REASON(RAND_R_NON_FIPS_METHOD)      ,"non fips method"},
+{ERR_REASON(RAND_R_NOT_IN_TEST_MODE)     ,"not in test mode"},
+{ERR_REASON(RAND_R_NO_KEY_SET)           ,"no key set"},
+{ERR_REASON(RAND_R_PRNG_ASKING_FOR_TOO_MUCH),"prng asking for too much"},
+{ERR_REASON(RAND_R_PRNG_ERROR)           ,"prng error"},
+{ERR_REASON(RAND_R_PRNG_KEYED)           ,"prng keyed"},
+{ERR_REASON(RAND_R_PRNG_NOT_REKEYED)     ,"prng not rekeyed"},
+{ERR_REASON(RAND_R_PRNG_NOT_RESEEDED)    ,"prng not reseeded"},
 {ERR_REASON(RAND_R_PRNG_NOT_SEEDED)      ,"PRNG not seeded"},
+{ERR_REASON(RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY),"prng seed must not match key"},
+{ERR_REASON(RAND_R_PRNG_STUCK)           ,"prng stuck"},
 {0,NULL}
 	};
 
diff --git a/crypto/rand/rand_lcl.h b/crypto/rand/rand_lcl.h
index 618a8ec..18cc9b1 100644
--- a/crypto/rand/rand_lcl.h
+++ b/crypto/rand/rand_lcl.h
@@ -154,5 +154,16 @@
 #define	MD(a,b,c)		EVP_Digest(a,b,c,NULL,EVP_md2(), NULL)
 #endif
 
+#ifndef OPENSSL_NO_ENGINE
+void int_RAND_set_callbacks(
+	int (*set_rand_func)(const RAND_METHOD *meth,
+						const RAND_METHOD **pmeth),
+	const RAND_METHOD *(*get_rand_func)
+						(const RAND_METHOD **pmeth));
+int eng_RAND_set_rand_method(const RAND_METHOD *meth,
+				const RAND_METHOD **pmeth);
+const RAND_METHOD *eng_RAND_get_rand_method(const RAND_METHOD **pmeth);
+#endif
+
 
 #endif
diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c
index 513e338..da6b4e0 100644
--- a/crypto/rand/rand_lib.c
+++ b/crypto/rand/rand_lib.c
@@ -60,15 +60,82 @@
 #include <time.h>
 #include "cryptlib.h"
 #include <openssl/rand.h>
+#include "rand_lcl.h"
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#include <openssl/fips_rand.h>
+#endif
+
 #ifndef OPENSSL_NO_ENGINE
 #include <openssl/engine.h>
 #endif
 
+static const RAND_METHOD *default_RAND_meth = NULL;
+
+#ifdef OPENSSL_FIPS
+
+static int fips_RAND_set_rand_method(const RAND_METHOD *meth,
+					const RAND_METHOD **pmeth)
+	{
+	*pmeth = meth;
+	return 1;
+	}
+
+static const RAND_METHOD *fips_RAND_get_rand_method(const RAND_METHOD **pmeth)
+	{
+	if (!*pmeth)
+		{
+		if(FIPS_mode())
+			*pmeth=FIPS_rand_method();
+		else
+			*pmeth = RAND_SSLeay();
+		}
+
+	if(FIPS_mode()
+		&& *pmeth != FIPS_rand_check())
+	    {
+	    RANDerr(RAND_F_FIPS_RAND_GET_RAND_METHOD,RAND_R_NON_FIPS_METHOD);
+	    return 0;
+	    }
+
+	return *pmeth;
+	}
+
+static int (*RAND_set_rand_method_func)(const RAND_METHOD *meth,
+						const RAND_METHOD **pmeth)
+	= fips_RAND_set_rand_method;
+static const RAND_METHOD *(*RAND_get_rand_method_func)
+						(const RAND_METHOD **pmeth)
+	= fips_RAND_get_rand_method;
+
+#ifndef OPENSSL_NO_ENGINE
+void int_RAND_set_callbacks(
+	int (*set_rand_func)(const RAND_METHOD *meth,
+						const RAND_METHOD **pmeth),
+	const RAND_METHOD *(*get_rand_func)
+						(const RAND_METHOD **pmeth))
+	{
+	RAND_set_rand_method_func = set_rand_func;
+	RAND_get_rand_method_func = get_rand_func;
+	}
+#endif
+
+int RAND_set_rand_method(const RAND_METHOD *meth)
+	{
+	return RAND_set_rand_method_func(meth, &default_RAND_meth);
+	}
+
+const RAND_METHOD *RAND_get_rand_method(void)
+	{
+	return RAND_get_rand_method_func(&default_RAND_meth);
+	}
+
+#else
+
 #ifndef OPENSSL_NO_ENGINE
 /* non-NULL if default_RAND_meth is ENGINE-provided */
 static ENGINE *funct_ref =NULL;
 #endif
-static const RAND_METHOD *default_RAND_meth = NULL;
 
 int RAND_set_rand_method(const RAND_METHOD *meth)
 	{
@@ -129,6 +196,8 @@
 	}
 #endif
 
+#endif
+
 void RAND_cleanup(void)
 	{
 	const RAND_METHOD *meth = RAND_get_rand_method();
diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c
index 6c2be5c..71b98ec 100644
--- a/crypto/rand/rand_unix.c
+++ b/crypto/rand/rand_unix.c
@@ -232,7 +232,7 @@
 				t.tv_sec = 0;
 				t.tv_usec = usec;
 
-				if (FD_SETSIZE > 0 && fd >= FD_SETSIZE)
+				if (FD_SETSIZE > 0 && (unsigned)fd >= FD_SETSIZE)
 					{
 					/* can't use select, so just try to read once anyway */
 					try_read = 1;
diff --git a/crypto/rand/randfile.c b/crypto/rand/randfile.c
index 6c0ec9a..d108353 100644
--- a/crypto/rand/randfile.c
+++ b/crypto/rand/randfile.c
@@ -81,10 +81,25 @@
 # include <sys/stat.h>
 #endif
 
+#ifdef _WIN32
+#define stat	_stat
+#define chmod	_chmod
+#define open	_open
+#define fdopen	_fdopen
+#endif
+
 #undef BUFSIZE
 #define BUFSIZE	1024
 #define RAND_DATA 1024
 
+#ifdef OPENSSL_SYS_VMS
+/* This declaration is a nasty hack to get around vms' extension to fopen
+ * for passing in sharing options being disabled by our /STANDARD=ANSI89 */
+static FILE *(*const vms_fopen)(const char *, const char *, ...) =
+    (FILE *(*)(const char *, const char *, ...))fopen;
+#define VMS_OPEN_ATTRS "shr=get,put,upd,del","ctx=bin,stm","rfm=stm","rat=none","mrs=0"
+#endif
+
 /* #define RFILE ".rnd" - defined in ../../e_os.h */
 
 /* Note that these functions are intended for seed files only.
@@ -106,7 +121,11 @@
 	RAND_add(&sb,sizeof(sb),0.0);
 	if (bytes == 0) return(ret);
 
+#ifdef OPENSSL_SYS_VMS
+	in=vms_fopen(file,"rb",VMS_OPEN_ATTRS);
+#else
 	in=fopen(file,"rb");
+#endif
 	if (in == NULL) goto err;
 #if defined(S_IFBLK) && defined(S_IFCHR)
 	if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
@@ -167,7 +186,7 @@
 #endif
 	}
 
-#if defined(O_CREAT) && !defined(OPENSSL_SYS_WIN32)
+#if defined(O_CREAT) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_VMS)
 	{
 	/* For some reason Win32 can't write to files created this way */
 	
@@ -178,8 +197,34 @@
 		out = fdopen(fd, "wb");
 	}
 #endif
+
+#ifdef OPENSSL_SYS_VMS
+	/* VMS NOTE: Prior versions of this routine created a _new_
+	 * version of the rand file for each call into this routine, then
+	 * deleted all existing versions named ;-1, and finally renamed
+	 * the current version as ';1'. Under concurrent usage, this
+	 * resulted in an RMS race condition in rename() which could
+	 * orphan files (see vms message help for RMS$_REENT). With the
+	 * fopen() calls below, openssl/VMS now shares the top-level
+	 * version of the rand file. Note that there may still be
+	 * conditions where the top-level rand file is locked. If so, this
+	 * code will then create a new version of the rand file. Without
+	 * the delete and rename code, this can result in ascending file
+	 * versions that stop at version 32767, and this routine will then
+	 * return an error. The remedy for this is to recode the calling
+	 * application to avoid concurrent use of the rand file, or
+	 * synchronize usage at the application level. Also consider
+	 * whether or not you NEED a persistent rand file in a concurrent
+	 * use situation. 
+	 */
+
+	out = vms_fopen(file,"rb+",VMS_OPEN_ATTRS);
+	if (out == NULL)
+		out = vms_fopen(file,"wb",VMS_OPEN_ATTRS);
+#else
 	if (out == NULL)
 		out = fopen(file,"wb");
+#endif
 	if (out == NULL) goto err;
 
 #ifndef NO_CHMOD
@@ -201,25 +246,6 @@
 		ret+=i;
 		if (n <= 0) break;
                 }
-#ifdef OPENSSL_SYS_VMS
-	/* Try to delete older versions of the file, until there aren't
-	   any */
-	{
-	char *tmpf;
-
-	tmpf = OPENSSL_malloc(strlen(file) + 4);  /* to add ";-1" and a nul */
-	if (tmpf)
-		{
-		strcpy(tmpf, file);
-		strcat(tmpf, ";-1");
-		while(delete(tmpf) == 0)
-			;
-		rename(file,";1"); /* Make sure it's version 1, or we
-				      will reach the limit (32767) at
-				      some point... */
-		}
-	}
-#endif /* OPENSSL_SYS_VMS */
 
 	fclose(out);
 	OPENSSL_cleanse(buf,BUFSIZE);
diff --git a/crypto/rc2/Makefile b/crypto/rc2/Makefile
index 73eac34..4b6292b 100644
--- a/crypto/rc2/Makefile
+++ b/crypto/rc2/Makefile
@@ -33,7 +33,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -78,7 +78,11 @@
 rc2_cbc.o: rc2_cbc.c rc2_locl.h
 rc2_ecb.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
 rc2_ecb.o: ../../include/openssl/rc2.h rc2_ecb.c rc2_locl.h
-rc2_skey.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc2.h
+rc2_skey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+rc2_skey.o: ../../include/openssl/fips.h ../../include/openssl/opensslconf.h
+rc2_skey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rc2_skey.o: ../../include/openssl/rc2.h ../../include/openssl/safestack.h
+rc2_skey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 rc2_skey.o: rc2_locl.h rc2_skey.c
 rc2cfb64.o: ../../include/openssl/opensslconf.h ../../include/openssl/rc2.h
 rc2cfb64.o: rc2_locl.h rc2cfb64.c
diff --git a/crypto/rc2/rc2.h b/crypto/rc2/rc2.h
index 34c8362..e542ec9 100644
--- a/crypto/rc2/rc2.h
+++ b/crypto/rc2/rc2.h
@@ -79,7 +79,9 @@
 	RC2_INT data[64];
 	} RC2_KEY;
 
- 
+#ifdef OPENSSL_FIPS 
+void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits);
+#endif
 void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits);
 void RC2_ecb_encrypt(const unsigned char *in,unsigned char *out,RC2_KEY *key,
 		     int enc);
diff --git a/crypto/rc2/rc2_skey.c b/crypto/rc2/rc2_skey.c
index 4953642..4e000e5 100644
--- a/crypto/rc2/rc2_skey.c
+++ b/crypto/rc2/rc2_skey.c
@@ -57,6 +57,11 @@
  */
 
 #include <openssl/rc2.h>
+#include <openssl/crypto.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 #include "rc2_locl.h"
 
 static unsigned char key_table[256]={
@@ -94,8 +99,20 @@
  * BSAFE uses the 'retarded' version.  What I previously shipped is
  * the same as specifying 1024 for the 'bits' parameter.  Bsafe uses
  * a version where the bits parameter is the same as len*8 */
+
+#ifdef OPENSSL_FIPS
 void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits)
 	{
+	if (FIPS_mode())
+		FIPS_BAD_ABORT(RC2)
+	private_RC2_set_key(key, len, data, bits);
+	}
+void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,
+								int bits)
+#else
+void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits)
+#endif
+	{
 	int i,j;
 	unsigned char *k;
 	RC2_INT *ki;
diff --git a/crypto/rc4/Makefile b/crypto/rc4/Makefile
index 187ed5c..f0bd767 100644
--- a/crypto/rc4/Makefile
+++ b/crypto/rc4/Makefile
@@ -21,8 +21,8 @@
 APPS=
 
 LIB=$(TOP)/libcrypto.a
-LIBSRC=rc4_skey.c rc4_enc.c
-LIBOBJ=$(RC4_ENC)
+LIBSRC=rc4_skey.c rc4_enc.c rc4_fblk.c
+LIBOBJ=$(RC4_ENC) rc4_fblk.o
 
 SRC= $(LIBSRC)
 
@@ -37,7 +37,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -105,10 +105,20 @@
 rc4_enc.o: ../../include/openssl/rc4.h ../../include/openssl/safestack.h
 rc4_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 rc4_enc.o: ../cryptlib.h rc4_enc.c rc4_locl.h
+rc4_fblk.o: ../../e_os.h ../../include/openssl/bio.h
+rc4_fblk.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rc4_fblk.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+rc4_fblk.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+rc4_fblk.o: ../../include/openssl/opensslconf.h
+rc4_fblk.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rc4_fblk.o: ../../include/openssl/rc4.h ../../include/openssl/safestack.h
+rc4_fblk.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rc4_fblk.o: ../cryptlib.h rc4_fblk.c rc4_locl.h
 rc4_skey.o: ../../e_os.h ../../include/openssl/bio.h
 rc4_skey.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 rc4_skey.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rc4_skey.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+rc4_skey.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+rc4_skey.o: ../../include/openssl/opensslconf.h
 rc4_skey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 rc4_skey.o: ../../include/openssl/rc4.h ../../include/openssl/safestack.h
 rc4_skey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
diff --git a/crypto/rc4/asm/rc4-x86_64.pl b/crypto/rc4/asm/rc4-x86_64.pl
index 2d47320..00c6fa2 100755
--- a/crypto/rc4/asm/rc4-x86_64.pl
+++ b/crypto/rc4/asm/rc4-x86_64.pl
@@ -359,6 +359,8 @@
 
 $code =~ s/#([bwd])/$1/gm;
 
+$code =~ s/RC4_set_key/private_RC4_set_key/g if ($ENV{FIPSCANLIB} ne "");
+
 print $code;
 
 close STDOUT;
diff --git a/crypto/rc4/rc4.h b/crypto/rc4/rc4.h
index 7aec04f..2d8620d 100644
--- a/crypto/rc4/rc4.h
+++ b/crypto/rc4/rc4.h
@@ -76,6 +76,9 @@
 
  
 const char *RC4_options(void);
+#ifdef OPENSSL_FIPS
+void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
+#endif
 void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
 void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
 		unsigned char *outdata);
diff --git a/crypto/rc4/rc4_fblk.c b/crypto/rc4/rc4_fblk.c
new file mode 100644
index 0000000..1b2a429
--- /dev/null
+++ b/crypto/rc4/rc4_fblk.c
@@ -0,0 +1,75 @@
+/* crypto/rc4/rc4_fblk.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/rc4.h>
+#include "rc4_locl.h"
+#include <openssl/opensslv.h>
+#include <openssl/crypto.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
+/* FIPS mode blocking for RC4 has to be done separately since RC4_set_key
+ * may be implemented in an assembly language file.
+ */
+
+#ifdef OPENSSL_FIPS
+void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
+	{
+	if (FIPS_mode())
+		FIPS_BAD_ABORT(RC4)
+	private_RC4_set_key(key, len, data);
+	}
+#endif
+
diff --git a/crypto/rc4/rc4_skey.c b/crypto/rc4/rc4_skey.c
index 46b77ec..4478d1a 100644
--- a/crypto/rc4/rc4_skey.c
+++ b/crypto/rc4/rc4_skey.c
@@ -59,6 +59,11 @@
 #include <openssl/rc4.h>
 #include "rc4_locl.h"
 #include <openssl/opensslv.h>
+#include <openssl/crypto.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 
 const char RC4_version[]="RC4" OPENSSL_VERSION_PTEXT;
 
@@ -85,7 +90,11 @@
  * Date: Wed, 14 Sep 1994 06:35:31 GMT
  */
 
+#ifdef OPENSSL_FIPS
+void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
+#else
 void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
+#endif
 	{
         register RC4_INT tmp;
         register int id1,id2;
@@ -127,7 +136,12 @@
 		 *
 		 *				<appro@fy.chalmers.se>
 		 */
-		if (OPENSSL_ia32cap_P & (1<<20)) {
+#ifdef OPENSSL_FIPS
+		unsigned long *ia32cap_ptr = OPENSSL_ia32cap_loc();
+		if (ia32cap_ptr && (*ia32cap_ptr & (1<<28))) {
+#else
+		if (OPENSSL_ia32cap_P & (1<<28)) {
+#endif
 			unsigned char *cp=(unsigned char *)d;
 
 			for (i=0;i<256;i++) cp[i]=i;
diff --git a/crypto/ripemd/Makefile b/crypto/ripemd/Makefile
index d55875c..6145f13 100644
--- a/crypto/ripemd/Makefile
+++ b/crypto/ripemd/Makefile
@@ -38,7 +38,7 @@
 all:    lib
 
 lib:    $(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -89,8 +89,13 @@
 
 # DO NOT DELETE THIS LINE -- make depend depends on it.
 
-rmd_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-rmd_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ripemd.h
+rmd_dgst.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+rmd_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+rmd_dgst.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+rmd_dgst.o: ../../include/openssl/opensslconf.h
+rmd_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rmd_dgst.o: ../../include/openssl/ripemd.h ../../include/openssl/safestack.h
+rmd_dgst.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 rmd_dgst.o: ../md32_common.h rmd_dgst.c rmd_locl.h rmdconst.h
 rmd_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 rmd_one.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
diff --git a/crypto/ripemd/README b/crypto/ripemd/README
index 7097707..f1ffc8b 100644
--- a/crypto/ripemd/README
+++ b/crypto/ripemd/README
@@ -4,7 +4,7 @@
 This is my implementation of RIPEMD-160.  The pentium assember is a little
 off the pace since I only get 1050 cycles, while the best is 1013.
 I have a few ideas for how to get another 20 or so cycles, but at
-this point I will not bother right now.  I belive the trick will be
+this point I will not bother right now.  I believe the trick will be
 to remove my 'copy X array onto stack' until inside the RIP1() finctions the
 first time round.  To do this I need another register and will only have one
 temporary one.  A bit tricky....  I can also cleanup the saving of the 5 words
diff --git a/crypto/ripemd/ripemd.h b/crypto/ripemd/ripemd.h
index 033a596..3b6d043 100644
--- a/crypto/ripemd/ripemd.h
+++ b/crypto/ripemd/ripemd.h
@@ -90,7 +90,9 @@
 	RIPEMD160_LONG data[RIPEMD160_LBLOCK];
 	unsigned int   num;
 	} RIPEMD160_CTX;
-
+#ifdef OPENSSL_FIPS
+int private_RIPEMD160_Init(RIPEMD160_CTX *c);
+#endif
 int RIPEMD160_Init(RIPEMD160_CTX *c);
 int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len);
 int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c);
diff --git a/crypto/ripemd/rmd_dgst.c b/crypto/ripemd/rmd_dgst.c
index 6162628..ead11d0 100644
--- a/crypto/ripemd/rmd_dgst.c
+++ b/crypto/ripemd/rmd_dgst.c
@@ -59,6 +59,11 @@
 #include <stdio.h>
 #include "rmd_locl.h"
 #include <openssl/opensslv.h>
+#include <openssl/err.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 
 const char RMD160_version[]="RIPE-MD160" OPENSSL_VERSION_PTEXT;
 
@@ -69,7 +74,7 @@
      void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p,size_t num);
 #  endif
 
-int RIPEMD160_Init(RIPEMD160_CTX *c)
+FIPS_NON_FIPS_MD_Init(RIPEMD160)
 	{
 	c->A=RIPEMD160_A;
 	c->B=RIPEMD160_B;
diff --git a/crypto/ripemd/rmd_locl.h b/crypto/ripemd/rmd_locl.h
index f14b346..ce12a80 100644
--- a/crypto/ripemd/rmd_locl.h
+++ b/crypto/ripemd/rmd_locl.h
@@ -72,7 +72,7 @@
  */
 #ifdef RMD160_ASM
 # if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__)
-#  define ripemd160_block_data_order ripemd160_block_asm_data_order
+#  define ripemd160_block_host_order ripemd160_block_asm_data_order
 # endif
 #endif
 
diff --git a/crypto/rsa/Makefile b/crypto/rsa/Makefile
index 1390081..7b1fd64 100644
--- a/crypto/rsa/Makefile
+++ b/crypto/rsa/Makefile
@@ -19,10 +19,10 @@
 LIB=$(TOP)/libcrypto.a
 LIBSRC= rsa_eay.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_saos.c rsa_err.c \
 	rsa_pk1.c rsa_ssl.c rsa_none.c rsa_oaep.c rsa_chk.c rsa_null.c \
-	rsa_pss.c rsa_x931.c rsa_asn1.c rsa_depr.c
+	rsa_pss.c rsa_x931.c rsa_x931g.c rsa_asn1.c rsa_depr.c rsa_eng.c
 LIBOBJ= rsa_eay.o rsa_gen.o rsa_lib.o rsa_sign.o rsa_saos.o rsa_err.o \
 	rsa_pk1.o rsa_ssl.o rsa_none.o rsa_oaep.o rsa_chk.o rsa_null.o \
-	rsa_pss.o rsa_x931.o rsa_asn1.o rsa_depr.o
+	rsa_pss.o rsa_x931.o rsa_x931g.o rsa_asn1.o rsa_depr.o rsa_eng.o
 
 SRC= $(LIBSRC)
 
@@ -37,7 +37,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -114,6 +114,21 @@
 rsa_eay.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
 rsa_eay.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 rsa_eay.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_eay.c
+rsa_eng.o: ../../e_os.h ../../include/openssl/asn1.h
+rsa_eng.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
+rsa_eng.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
+rsa_eng.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+rsa_eng.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+rsa_eng.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+rsa_eng.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+rsa_eng.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rsa_eng.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rsa_eng.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_eng.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+rsa_eng.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+rsa_eng.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+rsa_eng.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+rsa_eng.o: ../../include/openssl/x509_vfy.h ../cryptlib.h rsa_eng.c
 rsa_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 rsa_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 rsa_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
@@ -133,13 +148,18 @@
 rsa_lib.o: ../../e_os.h ../../include/openssl/asn1.h
 rsa_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 rsa_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-rsa_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h
-rsa_lib.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
-rsa_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-rsa_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+rsa_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+rsa_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
+rsa_lib.o: ../../include/openssl/engine.h ../../include/openssl/err.h
+rsa_lib.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+rsa_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rsa_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rsa_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
 rsa_lib.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-rsa_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-rsa_lib.o: ../cryptlib.h rsa_lib.c
+rsa_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+rsa_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+rsa_lib.o: ../../include/openssl/x509_vfy.h ../cryptlib.h rsa_lib.c
 rsa_none.o: ../../e_os.h ../../include/openssl/asn1.h
 rsa_none.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 rsa_none.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
@@ -162,9 +182,9 @@
 rsa_oaep.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 rsa_oaep.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 rsa_oaep.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_oaep.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-rsa_oaep.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-rsa_oaep.o: ../../include/openssl/opensslconf.h
+rsa_oaep.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+rsa_oaep.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rsa_oaep.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 rsa_oaep.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 rsa_oaep.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
 rsa_oaep.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
@@ -183,21 +203,23 @@
 rsa_pss.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 rsa_pss.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 rsa_pss.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-rsa_pss.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-rsa_pss.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-rsa_pss.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-rsa_pss.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-rsa_pss.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-rsa_pss.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-rsa_pss.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_pss.c
+rsa_pss.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+rsa_pss.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+rsa_pss.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rsa_pss.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_pss.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
+rsa_pss.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+rsa_pss.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rsa_pss.o: ../cryptlib.h rsa_pss.c
 rsa_saos.o: ../../e_os.h ../../include/openssl/asn1.h
 rsa_saos.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
 rsa_saos.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 rsa_saos.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 rsa_saos.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 rsa_saos.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-rsa_saos.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-rsa_saos.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rsa_saos.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+rsa_saos.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+rsa_saos.o: ../../include/openssl/opensslconf.h
 rsa_saos.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 rsa_saos.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
 rsa_saos.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
@@ -210,8 +232,9 @@
 rsa_sign.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 rsa_sign.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 rsa_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-rsa_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-rsa_sign.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+rsa_sign.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+rsa_sign.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+rsa_sign.o: ../../include/openssl/opensslconf.h
 rsa_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 rsa_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
 rsa_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
@@ -237,3 +260,11 @@
 rsa_x931.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
 rsa_x931.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
 rsa_x931.o: ../../include/openssl/symhacks.h ../cryptlib.h rsa_x931.c
+rsa_x931g.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+rsa_x931g.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+rsa_x931g.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+rsa_x931g.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+rsa_x931g.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+rsa_x931g.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
+rsa_x931g.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+rsa_x931g.o: rsa_x931g.c
diff --git a/crypto/rsa/rsa.h b/crypto/rsa/rsa.h
index 6b5e4f8..5bb932a 100644
--- a/crypto/rsa/rsa.h
+++ b/crypto/rsa/rsa.h
@@ -74,6 +74,25 @@
 #error RSA is disabled.
 #endif
 
+/* If this flag is set the RSA method is FIPS compliant and can be used
+ * in FIPS mode. This is set in the validated module method. If an
+ * application sets this flag in its own methods it is its reposibility
+ * to ensure the result is compliant.
+ */
+
+#define RSA_FLAG_FIPS_METHOD			0x0400
+
+/* If this flag is set the operations normally disabled in FIPS mode are
+ * permitted it is then the applications responsibility to ensure that the
+ * usage is compliant.
+ */
+
+#define RSA_FLAG_NON_FIPS_ALLOW			0x0400
+
+#ifdef OPENSSL_FIPS
+#define FIPS_RSA_SIZE_T	int
+#endif
+
 #ifdef  __cplusplus
 extern "C" {
 #endif
@@ -163,6 +182,8 @@
 # define OPENSSL_RSA_MAX_MODULUS_BITS	16384
 #endif
 
+#define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS 1024
+
 #ifndef OPENSSL_RSA_SMALL_MODULUS_BITS
 # define OPENSSL_RSA_SMALL_MODULUS_BITS	3072
 #endif
@@ -240,6 +261,11 @@
 
 /* New version */
 int	RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
+int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2,
+			const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp,
+			const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq,
+			const BIGNUM *e, BN_GENCB *cb);
+int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb);
 
 int	RSA_check_key(const RSA *);
 	/* next 4 return -1 on error */
@@ -257,6 +283,11 @@
 
 int	RSA_flags(const RSA *r);
 
+#ifdef OPENSSL_FIPS
+RSA *FIPS_rsa_new(void);
+void FIPS_rsa_free(RSA *r);
+#endif
+
 void RSA_set_default_method(const RSA_METHOD *meth);
 const RSA_METHOD *RSA_get_default_method(void);
 const RSA_METHOD *RSA_get_method(const RSA *rsa);
@@ -281,6 +312,7 @@
 int	RSA_print(BIO *bp, const RSA *r,int offset);
 #endif
 
+#ifndef OPENSSL_NO_RC4
 int i2d_RSA_NET(const RSA *a, unsigned char **pp,
 		int (*cb)(char *buf, int len, const char *prompt, int verify),
 		int sgckey);
@@ -294,6 +326,7 @@
 RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
 		      int (*cb)(char *buf, int len, const char *prompt,
 				int verify));
+#endif
 
 /* The following 2 functions sign and verify a X509_SIG ASN1 object
  * inside PKCS#1 padded RSA encryption */
@@ -368,6 +401,8 @@
 /* Error codes for the RSA functions. */
 
 /* Function codes. */
+#define RSA_F_FIPS_RSA_SIGN				 140
+#define RSA_F_FIPS_RSA_VERIFY				 141
 #define RSA_F_MEMORY_LOCK				 100
 #define RSA_F_RSA_BUILTIN_KEYGEN			 129
 #define RSA_F_RSA_CHECK_KEY				 123
@@ -399,7 +434,11 @@
 #define RSA_F_RSA_PADDING_CHECK_X931			 128
 #define RSA_F_RSA_PRINT					 115
 #define RSA_F_RSA_PRINT_FP				 116
+#define RSA_F_RSA_PRIVATE_ENCRYPT			 137
+#define RSA_F_RSA_PUBLIC_DECRYPT			 138
 #define RSA_F_RSA_SETUP_BLINDING			 136
+#define RSA_F_RSA_SET_DEFAULT_METHOD			 139
+#define RSA_F_RSA_SET_METHOD				 142
 #define RSA_F_RSA_SIGN					 117
 #define RSA_F_RSA_SIGN_ASN1_OCTET_STRING		 118
 #define RSA_F_RSA_VERIFY				 119
@@ -433,10 +472,12 @@
 #define RSA_R_KEY_SIZE_TOO_SMALL			 120
 #define RSA_R_LAST_OCTET_INVALID			 134
 #define RSA_R_MODULUS_TOO_LARGE				 105
+#define RSA_R_NON_FIPS_METHOD				 141
 #define RSA_R_NO_PUBLIC_EXPONENT			 140
 #define RSA_R_NULL_BEFORE_BLOCK_MISSING			 113
 #define RSA_R_N_DOES_NOT_EQUAL_P_Q			 127
 #define RSA_R_OAEP_DECODING_ERROR			 121
+#define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE	 142
 #define RSA_R_PADDING_CHECK_FAILED			 114
 #define RSA_R_P_NOT_PRIME				 128
 #define RSA_R_Q_NOT_PRIME				 129
diff --git a/crypto/rsa/rsa_asn1.c b/crypto/rsa/rsa_asn1.c
index bbbf26d..6e8a803 100644
--- a/crypto/rsa/rsa_asn1.c
+++ b/crypto/rsa/rsa_asn1.c
@@ -1,5 +1,5 @@
 /* rsa_asn1.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/crypto/rsa/rsa_eay.c b/crypto/rsa/rsa_eay.c
index ffadaab..0ac6418 100644
--- a/crypto/rsa/rsa_eay.c
+++ b/crypto/rsa/rsa_eay.c
@@ -115,7 +115,7 @@
 #include <openssl/rsa.h>
 #include <openssl/rand.h>
 
-#ifndef RSA_NULL
+#if !defined(RSA_NULL) && !defined(OPENSSL_FIPS)
 
 static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
 		unsigned char *to, RSA *rsa,int padding);
@@ -150,16 +150,6 @@
 	return(&rsa_pkcs1_eay_meth);
 	}
 
-/* Usage example;
- *    MONT_HELPER(rsa->_method_mod_p, bn_ctx, rsa->p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
- */
-#define MONT_HELPER(method_mod, ctx, m, pre_cond, err_instr) \
-	if ((pre_cond) && ((method_mod) == NULL) && \
-			!BN_MONT_CTX_set_locked(&(method_mod), \
-				CRYPTO_LOCK_RSA, \
-				(m), (ctx))) \
-		err_instr
-
 static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
 	     unsigned char *to, RSA *rsa, int padding)
 	{
@@ -233,7 +223,9 @@
 		goto err;
 		}
 
-	MONT_HELPER(rsa->_method_mod_n, ctx, rsa->n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
+	if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+		if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+			goto err;
 
 	if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
 		rsa->_method_mod_n)) goto err;
@@ -438,7 +430,9 @@
 		else
 			d= rsa->d;
 
-		MONT_HELPER(rsa->_method_mod_n, ctx, rsa->n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
+		if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+			if(!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+				goto err;
 
 		if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
 				rsa->_method_mod_n)) goto err;
@@ -559,7 +553,9 @@
 		else
 			d = rsa->d;
 
-		MONT_HELPER(rsa->_method_mod_n, ctx, rsa->n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
+		if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+			if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+				goto err;
 		if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
 				rsa->_method_mod_n))
 		  goto err;
@@ -669,7 +665,9 @@
 		goto err;
 		}
 
-	MONT_HELPER(rsa->_method_mod_n, ctx, rsa->n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
+	if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+		if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+			goto err;
 
 	if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
 		rsa->_method_mod_n)) goto err;
@@ -747,11 +745,18 @@
 			q = rsa->q;
 			}
 
-		MONT_HELPER(rsa->_method_mod_p, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
-		MONT_HELPER(rsa->_method_mod_q, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
+		if (rsa->flags & RSA_FLAG_CACHE_PRIVATE)
+			{
+			if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p, CRYPTO_LOCK_RSA, p, ctx))
+				goto err;
+			if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_q, CRYPTO_LOCK_RSA, q, ctx))
+				goto err;
+			}
 	}
 
-	MONT_HELPER(rsa->_method_mod_n, ctx, rsa->n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
+	if (rsa->flags & RSA_FLAG_CACHE_PUBLIC)
+		if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx))
+			goto err;
 
 	/* compute I mod q */
 	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
diff --git a/crypto/rsa/rsa_eng.c b/crypto/rsa/rsa_eng.c
new file mode 100644
index 0000000..383a704
--- /dev/null
+++ b/crypto/rsa/rsa_eng.c
@@ -0,0 +1,348 @@
+/* crypto/rsa/rsa_lib.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <openssl/crypto.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/rand.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+const char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT;
+
+static const RSA_METHOD *default_RSA_meth=NULL;
+
+RSA *RSA_new(void)
+	{
+	RSA *r=RSA_new_method(NULL);
+
+	return r;
+	}
+
+void RSA_set_default_method(const RSA_METHOD *meth)
+	{
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD))
+		{
+		RSAerr(RSA_F_RSA_SET_DEFAULT_METHOD, RSA_R_NON_FIPS_METHOD);
+		return;
+		}
+#endif
+	default_RSA_meth = meth;
+	}
+
+const RSA_METHOD *RSA_get_default_method(void)
+	{
+	if (default_RSA_meth == NULL)
+		{
+#ifdef RSA_NULL
+		default_RSA_meth=RSA_null_method();
+#else
+#if 0 /* was: #ifdef RSAref */
+		default_RSA_meth=RSA_PKCS1_RSAref();
+#else
+		default_RSA_meth=RSA_PKCS1_SSLeay();
+#endif
+#endif
+		}
+
+	return default_RSA_meth;
+	}
+
+const RSA_METHOD *RSA_get_method(const RSA *rsa)
+	{
+	return rsa->meth;
+	}
+
+int RSA_set_method(RSA *rsa, const RSA_METHOD *meth)
+	{
+	/* NB: The caller is specifically setting a method, so it's not up to us
+	 * to deal with which ENGINE it comes from. */
+	const RSA_METHOD *mtmp;
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode() && !(meth->flags & RSA_FLAG_FIPS_METHOD))
+		{
+		RSAerr(RSA_F_RSA_SET_METHOD, RSA_R_NON_FIPS_METHOD);
+		return 0;
+		}
+#endif
+	mtmp = rsa->meth;
+	if (mtmp->finish) mtmp->finish(rsa);
+#ifndef OPENSSL_NO_ENGINE
+	if (rsa->engine)
+		{
+		ENGINE_finish(rsa->engine);
+		rsa->engine = NULL;
+		}
+#endif
+	rsa->meth = meth;
+	if (meth->init) meth->init(rsa);
+	return 1;
+	}
+
+RSA *RSA_new_method(ENGINE *engine)
+	{
+	RSA *ret;
+
+	ret=(RSA *)OPENSSL_malloc(sizeof(RSA));
+	if (ret == NULL)
+		{
+		RSAerr(RSA_F_RSA_NEW_METHOD,ERR_R_MALLOC_FAILURE);
+		return NULL;
+		}
+
+	ret->meth = RSA_get_default_method();
+#ifndef OPENSSL_NO_ENGINE
+	if (engine)
+		{
+		if (!ENGINE_init(engine))
+			{
+			RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB);
+			OPENSSL_free(ret);
+			return NULL;
+			}
+		ret->engine = engine;
+		}
+	else
+		ret->engine = ENGINE_get_default_RSA();
+	if(ret->engine)
+		{
+		ret->meth = ENGINE_get_RSA(ret->engine);
+		if(!ret->meth)
+			{
+			RSAerr(RSA_F_RSA_NEW_METHOD,
+				ERR_R_ENGINE_LIB);
+			ENGINE_finish(ret->engine);
+			OPENSSL_free(ret);
+			return NULL;
+			}
+		}
+#endif
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode() && !(ret->meth->flags & RSA_FLAG_FIPS_METHOD))
+		{
+		RSAerr(RSA_F_RSA_NEW_METHOD, RSA_R_NON_FIPS_METHOD);
+#ifndef OPENSSL_NO_ENGINE
+		if (ret->engine)
+			ENGINE_finish(ret->engine);
+#endif
+		OPENSSL_free(ret);
+		return NULL;
+		}
+#endif
+
+	ret->pad=0;
+	ret->version=0;
+	ret->n=NULL;
+	ret->e=NULL;
+	ret->d=NULL;
+	ret->p=NULL;
+	ret->q=NULL;
+	ret->dmp1=NULL;
+	ret->dmq1=NULL;
+	ret->iqmp=NULL;
+	ret->references=1;
+	ret->_method_mod_n=NULL;
+	ret->_method_mod_p=NULL;
+	ret->_method_mod_q=NULL;
+	ret->blinding=NULL;
+	ret->mt_blinding=NULL;
+	ret->bignum_data=NULL;
+	ret->flags=ret->meth->flags;
+	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data);
+	if ((ret->meth->init != NULL) && !ret->meth->init(ret))
+		{
+#ifndef OPENSSL_NO_ENGINE
+		if (ret->engine)
+			ENGINE_finish(ret->engine);
+#endif
+		CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data);
+		OPENSSL_free(ret);
+		ret=NULL;
+		}
+	return(ret);
+	}
+
+void RSA_free(RSA *r)
+	{
+	int i;
+
+	if (r == NULL) return;
+
+	i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_RSA);
+#ifdef REF_PRINT
+	REF_PRINT("RSA",r);
+#endif
+	if (i > 0) return;
+#ifdef REF_CHECK
+	if (i < 0)
+		{
+		fprintf(stderr,"RSA_free, bad reference count\n");
+		abort();
+		}
+#endif
+
+	if (r->meth->finish)
+		r->meth->finish(r);
+#ifndef OPENSSL_NO_ENGINE
+	if (r->engine)
+		ENGINE_finish(r->engine);
+#endif
+
+	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data);
+
+	if (r->n != NULL) BN_clear_free(r->n);
+	if (r->e != NULL) BN_clear_free(r->e);
+	if (r->d != NULL) BN_clear_free(r->d);
+	if (r->p != NULL) BN_clear_free(r->p);
+	if (r->q != NULL) BN_clear_free(r->q);
+	if (r->dmp1 != NULL) BN_clear_free(r->dmp1);
+	if (r->dmq1 != NULL) BN_clear_free(r->dmq1);
+	if (r->iqmp != NULL) BN_clear_free(r->iqmp);
+	if (r->blinding != NULL) BN_BLINDING_free(r->blinding);
+	if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding);
+	if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data);
+	OPENSSL_free(r);
+	}
+
+int RSA_up_ref(RSA *r)
+	{
+	int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA);
+#ifdef REF_PRINT
+	REF_PRINT("RSA",r);
+#endif
+#ifdef REF_CHECK
+	if (i < 2)
+		{
+		fprintf(stderr, "RSA_up_ref, bad reference count\n");
+		abort();
+		}
+#endif
+	return ((i > 1) ? 1 : 0);
+	}
+
+int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
+        {
+	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp,
+				new_func, dup_func, free_func);
+        }
+
+int RSA_set_ex_data(RSA *r, int idx, void *arg)
+	{
+	return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
+	}
+
+void *RSA_get_ex_data(const RSA *r, int idx)
+	{
+	return(CRYPTO_get_ex_data(&r->ex_data,idx));
+	}
+
+int RSA_flags(const RSA *r)
+	{
+	return((r == NULL)?0:r->meth->flags);
+	}
+
+int RSA_memory_lock(RSA *r)
+	{
+	int i,j,k,off;
+	char *p;
+	BIGNUM *bn,**t[6],*b;
+	BN_ULONG *ul;
+
+	if (r->d == NULL) return(1);
+	t[0]= &r->d;
+	t[1]= &r->p;
+	t[2]= &r->q;
+	t[3]= &r->dmp1;
+	t[4]= &r->dmq1;
+	t[5]= &r->iqmp;
+	k=sizeof(BIGNUM)*6;
+	off=k/sizeof(BN_ULONG)+1;
+	j=1;
+	for (i=0; i<6; i++)
+		j+= (*t[i])->top;
+	if ((p=OPENSSL_malloc_locked((off+j)*sizeof(BN_ULONG))) == NULL)
+		{
+		RSAerr(RSA_F_RSA_MEMORY_LOCK,ERR_R_MALLOC_FAILURE);
+		return(0);
+		}
+	bn=(BIGNUM *)p;
+	ul=(BN_ULONG *)&(p[off]);
+	for (i=0; i<6; i++)
+		{
+		b= *(t[i]);
+		*(t[i])= &(bn[i]);
+		memcpy((char *)&(bn[i]),(char *)b,sizeof(BIGNUM));
+		bn[i].flags=BN_FLG_STATIC_DATA;
+		bn[i].d=ul;
+		memcpy((char *)ul,b->d,sizeof(BN_ULONG)*b->top);
+		ul+=b->top;
+		BN_clear_free(b);
+		}
+	
+	/* I should fix this so it can still be done */
+	r->flags&= ~(RSA_FLAG_CACHE_PRIVATE|RSA_FLAG_CACHE_PUBLIC);
+
+	r->bignum_data=p;
+	return(1);
+	}
diff --git a/crypto/rsa/rsa_err.c b/crypto/rsa/rsa_err.c
index fe3ba1b..501f5ea 100644
--- a/crypto/rsa/rsa_err.c
+++ b/crypto/rsa/rsa_err.c
@@ -1,6 +1,6 @@
 /* crypto/rsa/rsa_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2007 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
@@ -70,6 +70,8 @@
 
 static ERR_STRING_DATA RSA_str_functs[]=
 	{
+{ERR_FUNC(RSA_F_FIPS_RSA_SIGN),	"FIPS_RSA_SIGN"},
+{ERR_FUNC(RSA_F_FIPS_RSA_VERIFY),	"FIPS_RSA_VERIFY"},
 {ERR_FUNC(RSA_F_MEMORY_LOCK),	"MEMORY_LOCK"},
 {ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN),	"RSA_BUILTIN_KEYGEN"},
 {ERR_FUNC(RSA_F_RSA_CHECK_KEY),	"RSA_check_key"},
@@ -101,7 +103,11 @@
 {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931),	"RSA_padding_check_X931"},
 {ERR_FUNC(RSA_F_RSA_PRINT),	"RSA_print"},
 {ERR_FUNC(RSA_F_RSA_PRINT_FP),	"RSA_print_fp"},
+{ERR_FUNC(RSA_F_RSA_PRIVATE_ENCRYPT),	"RSA_private_encrypt"},
+{ERR_FUNC(RSA_F_RSA_PUBLIC_DECRYPT),	"RSA_public_decrypt"},
 {ERR_FUNC(RSA_F_RSA_SETUP_BLINDING),	"RSA_setup_blinding"},
+{ERR_FUNC(RSA_F_RSA_SET_DEFAULT_METHOD),	"RSA_set_default_method"},
+{ERR_FUNC(RSA_F_RSA_SET_METHOD),	"RSA_set_method"},
 {ERR_FUNC(RSA_F_RSA_SIGN),	"RSA_sign"},
 {ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING),	"RSA_sign_ASN1_OCTET_STRING"},
 {ERR_FUNC(RSA_F_RSA_VERIFY),	"RSA_verify"},
@@ -138,10 +144,12 @@
 {ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL)    ,"key size too small"},
 {ERR_REASON(RSA_R_LAST_OCTET_INVALID)    ,"last octet invalid"},
 {ERR_REASON(RSA_R_MODULUS_TOO_LARGE)     ,"modulus too large"},
+{ERR_REASON(RSA_R_NON_FIPS_METHOD)       ,"non fips method"},
 {ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT)    ,"no public exponent"},
 {ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING),"null before block missing"},
 {ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q)  ,"n does not equal p q"},
 {ERR_REASON(RSA_R_OAEP_DECODING_ERROR)   ,"oaep decoding error"},
+{ERR_REASON(RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE),"operation not allowed in fips mode"},
 {ERR_REASON(RSA_R_PADDING_CHECK_FAILED)  ,"padding check failed"},
 {ERR_REASON(RSA_R_P_NOT_PRIME)           ,"p not prime"},
 {ERR_REASON(RSA_R_Q_NOT_PRIME)           ,"q not prime"},
diff --git a/crypto/rsa/rsa_gen.c b/crypto/rsa/rsa_gen.c
index 767f7ab..41278f8 100644
--- a/crypto/rsa/rsa_gen.c
+++ b/crypto/rsa/rsa_gen.c
@@ -68,6 +68,8 @@
 #include <openssl/bn.h>
 #include <openssl/rsa.h>
 
+#ifndef OPENSSL_FIPS
+
 static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb);
 
 /* NB: this wrapper would normally be placed in rsa_lib.c and the static
@@ -217,3 +219,4 @@
 	return ok;
 	}
 
+#endif
diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c
index 104aa4c..5714841 100644
--- a/crypto/rsa/rsa_lib.c
+++ b/crypto/rsa/rsa_lib.c
@@ -67,215 +67,6 @@
 #include <openssl/engine.h>
 #endif
 
-const char RSA_version[]="RSA" OPENSSL_VERSION_PTEXT;
-
-static const RSA_METHOD *default_RSA_meth=NULL;
-
-RSA *RSA_new(void)
-	{
-	RSA *r=RSA_new_method(NULL);
-
-	return r;
-	}
-
-void RSA_set_default_method(const RSA_METHOD *meth)
-	{
-	default_RSA_meth = meth;
-	}
-
-const RSA_METHOD *RSA_get_default_method(void)
-	{
-	if (default_RSA_meth == NULL)
-		{
-#ifdef RSA_NULL
-		default_RSA_meth=RSA_null_method();
-#else
-#if 0 /* was: #ifdef RSAref */
-		default_RSA_meth=RSA_PKCS1_RSAref();
-#else
-		default_RSA_meth=RSA_PKCS1_SSLeay();
-#endif
-#endif
-		}
-
-	return default_RSA_meth;
-	}
-
-const RSA_METHOD *RSA_get_method(const RSA *rsa)
-	{
-	return rsa->meth;
-	}
-
-int RSA_set_method(RSA *rsa, const RSA_METHOD *meth)
-	{
-	/* NB: The caller is specifically setting a method, so it's not up to us
-	 * to deal with which ENGINE it comes from. */
-	const RSA_METHOD *mtmp;
-	mtmp = rsa->meth;
-	if (mtmp->finish) mtmp->finish(rsa);
-#ifndef OPENSSL_NO_ENGINE
-	if (rsa->engine)
-		{
-		ENGINE_finish(rsa->engine);
-		rsa->engine = NULL;
-		}
-#endif
-	rsa->meth = meth;
-	if (meth->init) meth->init(rsa);
-	return 1;
-	}
-
-RSA *RSA_new_method(ENGINE *engine)
-	{
-	RSA *ret;
-
-	ret=(RSA *)OPENSSL_malloc(sizeof(RSA));
-	if (ret == NULL)
-		{
-		RSAerr(RSA_F_RSA_NEW_METHOD,ERR_R_MALLOC_FAILURE);
-		return NULL;
-		}
-
-	ret->meth = RSA_get_default_method();
-#ifndef OPENSSL_NO_ENGINE
-	if (engine)
-		{
-		if (!ENGINE_init(engine))
-			{
-			RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB);
-			OPENSSL_free(ret);
-			return NULL;
-			}
-		ret->engine = engine;
-		}
-	else
-		ret->engine = ENGINE_get_default_RSA();
-	if(ret->engine)
-		{
-		ret->meth = ENGINE_get_RSA(ret->engine);
-		if(!ret->meth)
-			{
-			RSAerr(RSA_F_RSA_NEW_METHOD,
-				ERR_R_ENGINE_LIB);
-			ENGINE_finish(ret->engine);
-			OPENSSL_free(ret);
-			return NULL;
-			}
-		}
-#endif
-
-	ret->pad=0;
-	ret->version=0;
-	ret->n=NULL;
-	ret->e=NULL;
-	ret->d=NULL;
-	ret->p=NULL;
-	ret->q=NULL;
-	ret->dmp1=NULL;
-	ret->dmq1=NULL;
-	ret->iqmp=NULL;
-	ret->references=1;
-	ret->_method_mod_n=NULL;
-	ret->_method_mod_p=NULL;
-	ret->_method_mod_q=NULL;
-	ret->blinding=NULL;
-	ret->mt_blinding=NULL;
-	ret->bignum_data=NULL;
-	ret->flags=ret->meth->flags;
-	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data);
-	if ((ret->meth->init != NULL) && !ret->meth->init(ret))
-		{
-#ifndef OPENSSL_NO_ENGINE
-		if (ret->engine)
-			ENGINE_finish(ret->engine);
-#endif
-		CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data);
-		OPENSSL_free(ret);
-		ret=NULL;
-		}
-	return(ret);
-	}
-
-void RSA_free(RSA *r)
-	{
-	int i;
-
-	if (r == NULL) return;
-
-	i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_RSA);
-#ifdef REF_PRINT
-	REF_PRINT("RSA",r);
-#endif
-	if (i > 0) return;
-#ifdef REF_CHECK
-	if (i < 0)
-		{
-		fprintf(stderr,"RSA_free, bad reference count\n");
-		abort();
-		}
-#endif
-
-	if (r->meth->finish)
-		r->meth->finish(r);
-#ifndef OPENSSL_NO_ENGINE
-	if (r->engine)
-		ENGINE_finish(r->engine);
-#endif
-
-	CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data);
-
-	if (r->n != NULL) BN_clear_free(r->n);
-	if (r->e != NULL) BN_clear_free(r->e);
-	if (r->d != NULL) BN_clear_free(r->d);
-	if (r->p != NULL) BN_clear_free(r->p);
-	if (r->q != NULL) BN_clear_free(r->q);
-	if (r->dmp1 != NULL) BN_clear_free(r->dmp1);
-	if (r->dmq1 != NULL) BN_clear_free(r->dmq1);
-	if (r->iqmp != NULL) BN_clear_free(r->iqmp);
-	if (r->blinding != NULL) BN_BLINDING_free(r->blinding);
-	if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding);
-	if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data);
-	OPENSSL_free(r);
-	}
-
-int RSA_up_ref(RSA *r)
-	{
-	int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA);
-#ifdef REF_PRINT
-	REF_PRINT("RSA",r);
-#endif
-#ifdef REF_CHECK
-	if (i < 2)
-		{
-		fprintf(stderr, "RSA_up_ref, bad reference count\n");
-		abort();
-		}
-#endif
-	return ((i > 1) ? 1 : 0);
-	}
-
-int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
-	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
-        {
-	return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp,
-				new_func, dup_func, free_func);
-        }
-
-int RSA_set_ex_data(RSA *r, int idx, void *arg)
-	{
-	return(CRYPTO_set_ex_data(&r->ex_data,idx,arg));
-	}
-
-void *RSA_get_ex_data(const RSA *r, int idx)
-	{
-	return(CRYPTO_get_ex_data(&r->ex_data,idx));
-	}
-
-int RSA_size(const RSA *r)
-	{
-	return(BN_num_bytes(r->n));
-	}
-
 int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
 	     RSA *rsa, int padding)
 	{
@@ -285,6 +76,13 @@
 int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
 	     RSA *rsa, int padding)
 	{
+#ifdef OPENSSL_FIPS
+	if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+		{
+		RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+		return 0;
+		}
+#endif
 	return(rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding));
 	}
 
@@ -297,12 +95,19 @@
 int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
 	     RSA *rsa, int padding)
 	{
+#ifdef OPENSSL_FIPS
+	if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+		{
+		RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+		return 0;
+		}
+#endif
 	return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding));
 	}
 
-int RSA_flags(const RSA *r)
+int RSA_size(const RSA *r)
 	{
-	return((r == NULL)?0:r->meth->flags);
+	return(BN_num_bytes(r->n));
 	}
 
 void RSA_blinding_off(RSA *rsa)
@@ -427,48 +232,3 @@
 
 	return ret;
 }
-
-int RSA_memory_lock(RSA *r)
-	{
-	int i,j,k,off;
-	char *p;
-	BIGNUM *bn,**t[6],*b;
-	BN_ULONG *ul;
-
-	if (r->d == NULL) return(1);
-	t[0]= &r->d;
-	t[1]= &r->p;
-	t[2]= &r->q;
-	t[3]= &r->dmp1;
-	t[4]= &r->dmq1;
-	t[5]= &r->iqmp;
-	k=sizeof(BIGNUM)*6;
-	off=k/sizeof(BN_ULONG)+1;
-	j=1;
-	for (i=0; i<6; i++)
-		j+= (*t[i])->top;
-	if ((p=OPENSSL_malloc_locked((off+j)*sizeof(BN_ULONG))) == NULL)
-		{
-		RSAerr(RSA_F_RSA_MEMORY_LOCK,ERR_R_MALLOC_FAILURE);
-		return(0);
-		}
-	bn=(BIGNUM *)p;
-	ul=(BN_ULONG *)&(p[off]);
-	for (i=0; i<6; i++)
-		{
-		b= *(t[i]);
-		*(t[i])= &(bn[i]);
-		memcpy((char *)&(bn[i]),(char *)b,sizeof(BIGNUM));
-		bn[i].flags=BN_FLG_STATIC_DATA;
-		bn[i].d=ul;
-		memcpy((char *)ul,b->d,sizeof(BN_ULONG)*b->top);
-		ul+=b->top;
-		BN_clear_free(b);
-		}
-	
-	/* I should fix this so it can still be done */
-	r->flags&= ~(RSA_FLAG_CACHE_PRIVATE|RSA_FLAG_CACHE_PUBLIC);
-
-	r->bignum_data=p;
-	return(1);
-	}
diff --git a/crypto/rsa/rsa_null.c b/crypto/rsa/rsa_null.c
index 491572c..2f2202f 100644
--- a/crypto/rsa/rsa_null.c
+++ b/crypto/rsa/rsa_null.c
@@ -1,5 +1,5 @@
 /* rsa_null.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/rsa/rsa_oaep.c b/crypto/rsa/rsa_oaep.c
index 3652677..4d30c9d 100644
--- a/crypto/rsa/rsa_oaep.c
+++ b/crypto/rsa/rsa_oaep.c
@@ -187,7 +187,7 @@
 	int mdlen;
 
 	EVP_MD_CTX_init(&c);
-	mdlen = EVP_MD_size(dgst);
+	mdlen = M_EVP_MD_size(dgst);
 	for (i = 0; outlen < len; i++)
 		{
 		cnt[0] = (unsigned char)((i >> 24) & 255);
diff --git a/crypto/rsa/rsa_pss.c b/crypto/rsa/rsa_pss.c
index e19d18c..9b993ac 100644
--- a/crypto/rsa/rsa_pss.c
+++ b/crypto/rsa/rsa_pss.c
@@ -1,5 +1,5 @@
 /* rsa_pss.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2005.
  */
 /* ====================================================================
@@ -81,7 +81,7 @@
 	EVP_MD_CTX ctx;
 	unsigned char H_[EVP_MAX_MD_SIZE];
 
-	hLen = EVP_MD_size(Hash);
+	hLen = M_EVP_MD_size(Hash);
 	/*
 	 * Negative sLen has special meanings:
 	 *	-1	sLen == hLen
@@ -176,7 +176,7 @@
 	unsigned char *H, *salt = NULL, *p;
 	EVP_MD_CTX ctx;
 
-	hLen = EVP_MD_size(Hash);
+	hLen = M_EVP_MD_size(Hash);
 	/*
 	 * Negative sLen has special meanings:
 	 *	-1	sLen == hLen
diff --git a/crypto/rsa/rsa_sign.c b/crypto/rsa/rsa_sign.c
index 71aabee..5488c06 100644
--- a/crypto/rsa/rsa_sign.c
+++ b/crypto/rsa/rsa_sign.c
@@ -90,6 +90,14 @@
 		i = SSL_SIG_LENGTH;
 		s = m;
 	} else {
+	/* NB: in FIPS mode block anything that isn't a TLS signature */
+#ifdef OPENSSL_FIPS
+		if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+			{
+			RSAerr(RSA_F_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+			return 0;
+			}
+#endif
 		sig.algor= &algor;
 		sig.algor->algorithm=OBJ_nid2obj(type);
 		if (sig.algor->algorithm == NULL)
@@ -167,10 +175,22 @@
 		RSAerr(RSA_F_RSA_VERIFY,ERR_R_MALLOC_FAILURE);
 		goto err;
 		}
-	if((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH) ) {
+	if(dtype == NID_md5_sha1)
+		{
+		if (m_len != SSL_SIG_LENGTH)
+			{
 			RSAerr(RSA_F_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH);
 			goto err;
-	}
+			}
+		}
+	/* NB: in FIPS mode block anything that isn't a TLS signature */
+#ifdef OPENSSL_FIPS
+	else if(FIPS_mode() && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
+		{
+		RSAerr(RSA_F_RSA_VERIFY, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE);
+		return 0;
+		}
+#endif
 	i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING);
 
 	if (i <= 0) goto err;
diff --git a/crypto/rsa/rsa_ssl.c b/crypto/rsa/rsa_ssl.c
index ea72629..cfeff15 100644
--- a/crypto/rsa/rsa_ssl.c
+++ b/crypto/rsa/rsa_ssl.c
@@ -130,7 +130,7 @@
 		RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23,RSA_R_NULL_BEFORE_BLOCK_MISSING);
 		return(-1);
 		}
-	for (k= -8; k<0; k++)
+	for (k = -9; k<-1; k++)
 		{
 		if (p[k] !=  0x03) break;
 		}
diff --git a/crypto/rsa/rsa_x931.c b/crypto/rsa/rsa_x931.c
index e918654..21548e3 100644
--- a/crypto/rsa/rsa_x931.c
+++ b/crypto/rsa/rsa_x931.c
@@ -1,5 +1,5 @@
 /* rsa_x931.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2005.
  */
 /* ====================================================================
diff --git a/crypto/rsa/rsa_x931g.c b/crypto/rsa/rsa_x931g.c
new file mode 100644
index 0000000..bf94f8b
--- /dev/null
+++ b/crypto/rsa/rsa_x931g.c
@@ -0,0 +1,255 @@
+/* crypto/rsa/rsa_gen.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+
+#ifndef OPENSSL_FIPS
+
+/* X9.31 RSA key derivation and generation */
+
+int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2,
+			const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp,
+			const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq,
+			const BIGNUM *e, BN_GENCB *cb)
+	{
+	BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL;
+	BN_CTX *ctx=NULL,*ctx2=NULL;
+
+	if (!rsa) 
+		goto err;
+
+	ctx = BN_CTX_new();
+	if (!ctx) 
+		goto err;
+	BN_CTX_start(ctx);
+
+	r0 = BN_CTX_get(ctx);
+	r1 = BN_CTX_get(ctx);
+	r2 = BN_CTX_get(ctx);
+	r3 = BN_CTX_get(ctx);
+
+	if (r3 == NULL)
+		goto err;
+	if (!rsa->e)
+		{
+		rsa->e = BN_dup(e);
+		if (!rsa->e)
+			goto err;
+		}
+	else
+		e = rsa->e;
+
+	/* If not all parameters present only calculate what we can.
+	 * This allows test programs to output selective parameters.
+	 */
+
+	if (Xp && !rsa->p)
+		{
+		rsa->p = BN_new();
+		if (!rsa->p)
+			goto err;
+
+		if (!BN_X931_derive_prime_ex(rsa->p, p1, p2,
+					Xp, Xp1, Xp2, e, ctx, cb))
+			goto err;
+		}
+
+	if (Xq && !rsa->q)
+		{
+		rsa->q = BN_new();
+		if (!rsa->q)
+			goto err;
+		if (!BN_X931_derive_prime_ex(rsa->q, q1, q2,
+					Xq, Xq1, Xq2, e, ctx, cb))
+			goto err;
+		}
+
+	if (!rsa->p || !rsa->q)
+		{
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+		return 2;
+		}
+
+	/* Since both primes are set we can now calculate all remaining 
+	 * components.
+	 */
+
+	/* calculate n */
+	rsa->n=BN_new();
+	if (rsa->n == NULL)
+		goto err;
+	if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx))
+		goto err;
+
+	/* calculate d */
+	if (!BN_sub(r1,rsa->p,BN_value_one()))
+		goto err;	/* p-1 */
+	if (!BN_sub(r2,rsa->q,BN_value_one()))
+		goto err;	/* q-1 */
+	if (!BN_mul(r0,r1,r2,ctx))
+		goto err;	/* (p-1)(q-1) */
+
+	if (!BN_gcd(r3, r1, r2, ctx))
+		goto err;
+
+	if (!BN_div(r0, NULL, r0, r3, ctx))
+		goto err;	/* LCM((p-1)(q-1)) */
+
+	ctx2 = BN_CTX_new();
+	if (!ctx2)
+		goto err;
+
+	rsa->d=BN_mod_inverse(NULL,rsa->e,r0,ctx2);	/* d */
+	if (rsa->d == NULL)
+		goto err;
+
+	/* calculate d mod (p-1) */
+	rsa->dmp1=BN_new();
+	if (rsa->dmp1 == NULL)
+		goto err;
+	if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx))
+		goto err;
+
+	/* calculate d mod (q-1) */
+	rsa->dmq1=BN_new();
+	if (rsa->dmq1 == NULL)
+		goto err;
+	if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx))
+		goto err;
+
+	/* calculate inverse of q mod p */
+	rsa->iqmp=BN_mod_inverse(NULL,rsa->q,rsa->p,ctx2);
+
+	err:
+	if (ctx)
+		{
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+		}
+	if (ctx2)
+		BN_CTX_free(ctx2);
+	/* If this is set all calls successful */
+	if (rsa && rsa->iqmp != NULL)
+		return 1;
+
+	return 0;
+
+	}
+
+int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb)
+	{
+	int ok = 0;
+	BIGNUM *Xp = NULL, *Xq = NULL;
+	BN_CTX *ctx = NULL;
+	
+	ctx = BN_CTX_new();
+	if (!ctx)
+		goto error;
+
+	BN_CTX_start(ctx);
+	Xp = BN_CTX_get(ctx);
+	Xq = BN_CTX_get(ctx);
+	if (!BN_X931_generate_Xpq(Xp, Xq, bits, ctx))
+		goto error;
+
+	rsa->p = BN_new();
+	rsa->q = BN_new();
+	if (!rsa->p || !rsa->q)
+		goto error;
+
+	/* Generate two primes from Xp, Xq */
+
+	if (!BN_X931_generate_prime_ex(rsa->p, NULL, NULL, NULL, NULL, Xp,
+					e, ctx, cb))
+		goto error;
+
+	if (!BN_X931_generate_prime_ex(rsa->q, NULL, NULL, NULL, NULL, Xq,
+					e, ctx, cb))
+		goto error;
+
+	/* Since rsa->p and rsa->q are valid this call will just derive
+	 * remaining RSA components.
+	 */
+
+	if (!RSA_X931_derive_ex(rsa, NULL, NULL, NULL, NULL,
+				NULL, NULL, NULL, NULL, NULL, NULL, e, cb))
+		goto error;
+
+	ok = 1;
+
+	error:
+	if (ctx)
+		{
+		BN_CTX_end(ctx);
+		BN_CTX_free(ctx);
+		}
+
+	if (ok)
+		return 1;
+
+	return 0;
+
+	}
+
+#endif
diff --git a/crypto/s390xcpuid.S b/crypto/s390xcpuid.S
new file mode 100644
index 0000000..8500133
--- /dev/null
+++ b/crypto/s390xcpuid.S
@@ -0,0 +1,90 @@
+.text
+
+.globl	OPENSSL_cpuid_setup
+.type	OPENSSL_cpuid_setup,@function
+.align	16
+OPENSSL_cpuid_setup:
+	br	%r14		# reserved for future
+.size	OPENSSL_cpuid_setup,.-OPENSSL_cpuid_setup
+
+.globl	OPENSSL_s390x_facilities
+.type	OPENSSL_s390x_facilities,@function
+.align	16
+OPENSSL_s390x_facilities:
+	lghi	%r0,0
+	.long	0xb2b0f010	# stfle	16(%r15)
+	lg	%r2,16(%r15)
+	br	%r14
+.size	OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities
+
+.globl	OPENSSL_rdtsc
+.type	OPENSSL_rdtsc,@function
+.align	16
+OPENSSL_rdtsc:
+	stck	16(%r15)
+	lg	%r2,16(%r15)
+	br	%r14
+.size	OPENSSL_rdtsc,.-OPENSSL_rdtsc
+
+.globl	OPENSSL_atomic_add
+.type	OPENSSL_atomic_add,@function
+.align	16
+OPENSSL_atomic_add:
+	l	%r1,0(%r2)
+.Lspin:	lr	%r0,%r1
+	ar	%r0,%r3
+	cs	%r1,%r0,0(%r2)
+	brc	4,.Lspin
+	lgfr	%r2,%r0		# OpenSSL expects the new value
+	br	%r14
+.size	OPENSSL_atomic_add,.-OPENSSL_atomic_add
+
+.globl	OPENSSL_wipe_cpu
+.type	OPENSSL_wipe_cpu,@function
+.align	16
+OPENSSL_wipe_cpu:
+	xgr	%r0,%r0
+	xgr	%r1,%r1
+	lgr	%r2,%r15
+	xgr	%r3,%r3
+	xgr	%r4,%r4
+	lzdr	%f0
+	lzdr	%f1
+	lzdr	%f2
+	lzdr	%f3
+	lzdr	%f4
+	lzdr	%f5
+	lzdr	%f6
+	lzdr	%f7
+	br	%r14
+.size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
+
+.globl	OPENSSL_cleanse
+.type	OPENSSL_cleanse,@function
+.align	16
+OPENSSL_cleanse:
+	lghi	%r4,15
+	lghi	%r0,0
+	clgr	%r3,%r4
+	jh	.Lot
+.Little:
+	stc	%r0,0(%r2)
+	la	%r2,1(%r2)
+	brctg	%r3,.Little
+	br	%r14
+.align	4
+.Lot:	tmll	%r2,7
+	jz	.Laligned
+	stc	%r0,0(%r2)
+	la	%r2,1(%r2)
+	brctg	%r3,.Lot
+.Laligned:
+	srlg	%r4,%r3,3
+.Loop:	stg	%r0,0(%r2)
+	la	%r2,8(%r2)
+	brctg	%r4,.Loop
+	lghi	%r4,7
+	ngr	%r3,%r4
+	jnz	.Little
+	br	%r14
+.size	OPENSSL_cleanse,.-OPENSSL_cleanse
diff --git a/crypto/sha/Makefile b/crypto/sha/Makefile
index ac64fb6..f4741b9 100644
--- a/crypto/sha/Makefile
+++ b/crypto/sha/Makefile
@@ -38,7 +38,7 @@
 all:    lib
 
 lib:    $(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -59,7 +59,7 @@
 	(cd asm; $(PERL) sha512-sse2.pl a.out $(CFLAGS) $(PROCESSOR) > ../$@)
 
 sha1-ia64.s:   asm/sha1-ia64.pl
-	(cd asm; $(PERL) sha1-ia64.pl $(CFLAGS) ) > $@
+	(cd asm; $(PERL) sha1-ia64.pl ../$@ $(CFLAGS))
 sha256-ia64.s: asm/sha512-ia64.pl
 	(cd asm; $(PERL) sha512-ia64.pl ../$@ $(CFLAGS))
 sha512-ia64.s: asm/sha512-ia64.pl
@@ -113,24 +113,31 @@
 sha1_one.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
 sha1_one.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 sha1_one.o: sha1_one.c
-sha1dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
+sha1dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/fips.h
+sha1dgst.o: ../../include/openssl/opensslconf.h
 sha1dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/sha.h
 sha1dgst.o: ../md32_common.h sha1dgst.c sha_locl.h
 sha256.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-sha256.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-sha256.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
-sha256.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-sha256.o: ../../include/openssl/symhacks.h ../md32_common.h sha256.c
+sha256.o: ../../include/openssl/fips.h ../../include/openssl/opensslconf.h
+sha256.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+sha256.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+sha256.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+sha256.o: ../md32_common.h sha256.c
 sha512.o: ../../e_os.h ../../include/openssl/bio.h
 sha512.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
 sha512.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-sha512.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-sha512.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-sha512.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-sha512.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-sha512.o: ../cryptlib.h sha512.c
-sha_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-sha_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/sha.h
+sha512.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+sha512.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+sha512.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
+sha512.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+sha512.o: ../../include/openssl/symhacks.h ../cryptlib.h sha512.c
+sha_dgst.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+sha_dgst.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+sha_dgst.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+sha_dgst.o: ../../include/openssl/opensslconf.h
+sha_dgst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+sha_dgst.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+sha_dgst.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
 sha_dgst.o: ../md32_common.h sha_dgst.c sha_locl.h
 sha_one.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 sha_one.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
diff --git a/crypto/sha/asm/sha1-586.pl b/crypto/sha/asm/sha1-586.pl
index 0b4dab2..a787dd3 100644
--- a/crypto/sha/asm/sha1-586.pl
+++ b/crypto/sha/asm/sha1-586.pl
@@ -149,7 +149,7 @@
 	&add($f,$e);			# f+=ROTATE(a,5)
 	}
 
-&function_begin("sha1_block_data_order",16);
+&function_begin("sha1_block_data_order");
 	&mov($tmp1,&wparam(0));	# SHA_CTX *c
 	&mov($T,&wparam(1));	# const void *input
 	&mov($A,&wparam(2));	# size_t num
diff --git a/crypto/sha/asm/sha1-ia64.pl b/crypto/sha/asm/sha1-ia64.pl
index aa18c10..51c4f47 100644
--- a/crypto/sha/asm/sha1-ia64.pl
+++ b/crypto/sha/asm/sha1-ia64.pl
@@ -302,4 +302,5 @@
 stringz	"SHA1 block transform for IA64, CRYPTOGAMS by <appro\@openssl.org>"
 ___
 
+$output=shift and open STDOUT,">$output";
 print $code;
diff --git a/crypto/sha/asm/sha1-x86_64.pl b/crypto/sha/asm/sha1-x86_64.pl
old mode 100644
new mode 100755
diff --git a/crypto/sha/asm/sha512-x86_64.pl b/crypto/sha/asm/sha512-x86_64.pl
old mode 100644
new mode 100755
diff --git a/crypto/sha/sha.h b/crypto/sha/sha.h
index eed44d7..47a2c29 100644
--- a/crypto/sha/sha.h
+++ b/crypto/sha/sha.h
@@ -106,6 +106,9 @@
 	} SHA_CTX;
 
 #ifndef OPENSSL_NO_SHA0
+#ifdef OPENSSL_FIPS
+int private_SHA_Init(SHA_CTX *c);
+#endif
 int SHA_Init(SHA_CTX *c);
 int SHA_Update(SHA_CTX *c, const void *data, size_t len);
 int SHA_Final(unsigned char *md, SHA_CTX *c);
diff --git a/crypto/sha/sha1_one.c b/crypto/sha/sha1_one.c
index 7c65b60..4831174 100644
--- a/crypto/sha/sha1_one.c
+++ b/crypto/sha/sha1_one.c
@@ -61,7 +61,7 @@
 #include <openssl/sha.h>
 #include <openssl/crypto.h>
 
-#ifndef OPENSSL_NO_SHA1
+#if !defined(OPENSSL_NO_SHA1)
 unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md)
 	{
 	SHA_CTX c;
diff --git a/crypto/sha/sha1dgst.c b/crypto/sha/sha1dgst.c
index 50d1925..d31f078 100644
--- a/crypto/sha/sha1dgst.c
+++ b/crypto/sha/sha1dgst.c
@@ -63,6 +63,10 @@
 #define SHA_1
 
 #include <openssl/opensslv.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 
 const char SHA1_version[]="SHA1" OPENSSL_VERSION_PTEXT;
 
diff --git a/crypto/sha/sha256.c b/crypto/sha/sha256.c
index 867f90c..3256a83 100644
--- a/crypto/sha/sha256.c
+++ b/crypto/sha/sha256.c
@@ -12,12 +12,19 @@
 
 #include <openssl/crypto.h>
 #include <openssl/sha.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 #include <openssl/opensslv.h>
 
 const char SHA256_version[]="SHA-256" OPENSSL_VERSION_PTEXT;
 
 int SHA224_Init (SHA256_CTX *c)
 	{
+#ifdef OPENSSL_FIPS
+	FIPS_selftest_check();
+#endif
 	c->h[0]=0xc1059ed8UL;	c->h[1]=0x367cd507UL;
 	c->h[2]=0x3070dd17UL;	c->h[3]=0xf70e5939UL;
 	c->h[4]=0xffc00b31UL;	c->h[5]=0x68581511UL;
@@ -29,6 +36,9 @@
 
 int SHA256_Init (SHA256_CTX *c)
 	{
+#ifdef OPENSSL_FIPS
+	FIPS_selftest_check();
+#endif
 	c->h[0]=0x6a09e667UL;	c->h[1]=0xbb67ae85UL;
 	c->h[2]=0x3c6ef372UL;	c->h[3]=0xa54ff53aUL;
 	c->h[4]=0x510e527fUL;	c->h[5]=0x9b05688cUL;
diff --git a/crypto/sha/sha512.c b/crypto/sha/sha512.c
index 987fc07..f5ed468 100644
--- a/crypto/sha/sha512.c
+++ b/crypto/sha/sha512.c
@@ -5,6 +5,10 @@
  * ====================================================================
  */
 #include <openssl/opensslconf.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 #if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512)
 /*
  * IMPLEMENTATION NOTES.
@@ -61,6 +65,9 @@
 
 int SHA384_Init (SHA512_CTX *c)
 	{
+#ifdef OPENSSL_FIPS
+	FIPS_selftest_check();
+#endif
 	c->h[0]=U64(0xcbbb9d5dc1059ed8);
 	c->h[1]=U64(0x629a292a367cd507);
 	c->h[2]=U64(0x9159015a3070dd17);
@@ -76,6 +83,9 @@
 
 int SHA512_Init (SHA512_CTX *c)
 	{
+#ifdef OPENSSL_FIPS
+	FIPS_selftest_check();
+#endif
 	c->h[0]=U64(0x6a09e667f3bcc908);
 	c->h[1]=U64(0xbb67ae8584caa73b);
 	c->h[2]=U64(0x3c6ef372fe94f82b);
@@ -327,7 +337,7 @@
 				((SHA_LONG64)hi)<<32|lo;	})
 #   else
 #    define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\
-			 unsigned int hi=p[0],lo=p[1];		\
+			 unsigned int hi=p[0],lo=p[1];			\
 				asm ("bswapl %0; bswapl %1;"	\
 				: "=r"(lo),"=r"(hi)		\
 				: "0"(lo),"1"(hi));		\
diff --git a/crypto/sha/sha_dgst.c b/crypto/sha/sha_dgst.c
index 70eb560..598f4d7 100644
--- a/crypto/sha/sha_dgst.c
+++ b/crypto/sha/sha_dgst.c
@@ -57,6 +57,12 @@
  */
 
 #include <openssl/opensslconf.h>
+#include <openssl/crypto.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
+#include <openssl/err.h>
 #if !defined(OPENSSL_NO_SHA0) && !defined(OPENSSL_NO_SHA)
 
 #undef  SHA_1
diff --git a/crypto/sha/sha_locl.h b/crypto/sha/sha_locl.h
index e37e572..da46ddf 100644
--- a/crypto/sha/sha_locl.h
+++ b/crypto/sha/sha_locl.h
@@ -122,8 +122,15 @@
 #define INIT_DATA_h3 0x10325476UL
 #define INIT_DATA_h4 0xc3d2e1f0UL
 
+#if defined(SHA_0) && defined(OPENSSL_FIPS)
+FIPS_NON_FIPS_MD_Init(SHA)
+#else
 int HASH_INIT (SHA_CTX *c)
+#endif
 	{
+#if defined(SHA_1) && defined(OPENSSL_FIPS)
+	FIPS_selftest_check();
+#endif
 	c->h0=INIT_DATA_h0;
 	c->h1=INIT_DATA_h1;
 	c->h2=INIT_DATA_h2;
diff --git a/crypto/sparcv9cap.c b/crypto/sparcv9cap.c
new file mode 100644
index 0000000..5f31d20
--- /dev/null
+++ b/crypto/sparcv9cap.c
@@ -0,0 +1,154 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <openssl/bn.h>
+
+#define SPARCV9_TICK_PRIVILEGED	(1<<0)
+#define SPARCV9_PREFER_FPU	(1<<1)
+#define SPARCV9_VIS1		(1<<2)
+#define SPARCV9_VIS2		(1<<3)	/* reserved */
+#define SPARCV9_FMADD		(1<<4)	/* reserved for SPARC64 V */
+static int OPENSSL_sparcv9cap_P=SPARCV9_TICK_PRIVILEGED;
+
+int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num)
+	{
+	int bn_mul_mont_fpu(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
+	int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
+
+	if ((OPENSSL_sparcv9cap_P&(SPARCV9_PREFER_FPU|SPARCV9_VIS1)) ==
+		(SPARCV9_PREFER_FPU|SPARCV9_VIS1))
+		return bn_mul_mont_fpu(rp,ap,bp,np,n0,num);
+	else
+		return bn_mul_mont_int(rp,ap,bp,np,n0,num);
+	}
+
+unsigned long OPENSSL_rdtsc(void)
+	{
+	unsigned long _sparcv9_rdtick(void);
+
+	if (OPENSSL_sparcv9cap_P&SPARCV9_TICK_PRIVILEGED)
+#if defined(__sun) && defined(__SVR4)
+		return gethrtime();
+#else
+		return 0;
+#endif
+	else
+		return _sparcv9_rdtick();
+	}
+
+#if defined(__sun) && defined(__SVR4)
+
+#include <dlfcn.h>
+#include <libdevinfo.h>
+#include <sys/systeminfo.h>
+
+typedef di_node_t (*di_init_t)(const char *,uint_t);
+typedef void      (*di_fini_t)(di_node_t);
+typedef char *    (*di_node_name_t)(di_node_t);
+typedef int       (*di_walk_node_t)(di_node_t,uint_t,di_node_name_t,int (*)(di_node_t,di_node_name_t));
+
+#define DLLINK(h,name) (name=(name##_t)dlsym((h),#name))
+
+static int walk_nodename(di_node_t node, di_node_name_t di_node_name)
+	{
+	char *name = (*di_node_name)(node);
+
+	/* This is expected to catch all UltraSPARC flavors prior T1 */
+	if (!strcmp (name,"SUNW,UltraSPARC") ||
+	    !strncmp(name,"SUNW,UltraSPARC-I",17))  /* covers II,III,IV */
+		{
+		OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU|SPARCV9_VIS1;
+
+		/* %tick is privileged only on UltraSPARC-I/II, but not IIe */
+		if (name[14]!='\0' && name[17]!='\0' && name[18]!='\0')
+			OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
+
+		return DI_WALK_TERMINATE;
+		}
+	/* This is expected to catch remaining UltraSPARCs, such as T1 */
+	else if (!strncmp(name,"SUNW,UltraSPARC",15))
+		{
+		OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
+
+		return DI_WALK_TERMINATE;
+		}
+
+	return DI_WALK_CONTINUE;
+	}
+
+void OPENSSL_cpuid_setup(void)
+	{
+	void *h;
+	char *e,si[256];
+	static int trigger=0;
+
+	if (trigger) return;
+	trigger=1;
+
+	if ((e=getenv("OPENSSL_sparcv9cap")))
+		{
+		OPENSSL_sparcv9cap_P=strtoul(e,NULL,0);
+		return;
+		}
+
+	if (sysinfo(SI_MACHINE,si,sizeof(si))>0)
+		{
+		if (strcmp(si,"sun4v"))
+			/* FPU is preferred for all CPUs, but US-T1/2 */
+			OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU;
+		}
+
+	if (sysinfo(SI_ISALIST,si,sizeof(si))>0)
+		{
+		if (strstr(si,"+vis"))
+			OPENSSL_sparcv9cap_P |= SPARCV9_VIS1;
+		if (strstr(si,"+vis2"))
+			{
+			OPENSSL_sparcv9cap_P |= SPARCV9_VIS2;
+			OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
+			return;
+			}
+		}
+
+	if ((h = dlopen("libdevinfo.so.1",RTLD_LAZY))) do
+		{
+		di_init_t	di_init;
+		di_fini_t	di_fini;
+		di_walk_node_t	di_walk_node;
+		di_node_name_t	di_node_name;
+		di_node_t	root_node;
+
+		if (!DLLINK(h,di_init))		break;
+		if (!DLLINK(h,di_fini))		break;
+		if (!DLLINK(h,di_walk_node))	break;
+		if (!DLLINK(h,di_node_name))	break;
+
+		if ((root_node = (*di_init)("/",DINFOSUBTREE))!=DI_NODE_NIL)
+			{
+			(*di_walk_node)(root_node,DI_WALK_SIBFIRST,
+					di_node_name,walk_nodename);
+			(*di_fini)(root_node);
+			}
+		} while(0);
+
+	if (h) dlclose(h);
+	}
+
+#else
+
+void OPENSSL_cpuid_setup(void)
+	{
+	char *e;
+ 
+	if ((e=getenv("OPENSSL_sparcv9cap")))
+		{
+		OPENSSL_sparcv9cap_P=strtoul(e,NULL,0);
+		return;
+		}
+
+	/* For now we assume that the rest supports UltraSPARC-I* only */
+	OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU|SPARCV9_VIS1;
+	}
+
+#endif
diff --git a/crypto/stack/Makefile b/crypto/stack/Makefile
index 5327692..489a77b 100644
--- a/crypto/stack/Makefile
+++ b/crypto/stack/Makefile
@@ -33,7 +33,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
diff --git a/crypto/stack/safestack.h b/crypto/stack/safestack.h
index 78cc485..40b1790 100644
--- a/crypto/stack/safestack.h
+++ b/crypto/stack/safestack.h
@@ -986,6 +986,50 @@
 #define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st))
 #define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st))
 
+#define sk_MIME_HEADER_new(st) SKM_sk_new(MIME_HEADER, (st))
+#define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER)
+#define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st))
+#define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st))
+#define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i))
+#define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val))
+#define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st))
+#define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i))
+#define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr))
+#define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i))
+#define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp))
+#define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st)
+#define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func))
+#define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st))
+#define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st))
+#define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st))
+#define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st))
+
+#define sk_MIME_PARAM_new(st) SKM_sk_new(MIME_PARAM, (st))
+#define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM)
+#define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st))
+#define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st))
+#define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i))
+#define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val))
+#define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st))
+#define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i))
+#define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr))
+#define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i))
+#define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp))
+#define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st)
+#define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func))
+#define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st))
+#define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st))
+#define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st))
+#define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st))
+
 #define sk_MIME_PARAM_new(st) SKM_sk_new(MIME_PARAM, (st))
 #define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM)
 #define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st))
diff --git a/crypto/store/Makefile b/crypto/store/Makefile
index 0dcfd78..c9f5d00 100644
--- a/crypto/store/Makefile
+++ b/crypto/store/Makefile
@@ -35,7 +35,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -89,14 +89,14 @@
 str_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 str_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
 str_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-str_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-str_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-str_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-str_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-str_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-str_lib.o: ../../include/openssl/store.h ../../include/openssl/symhacks.h
-str_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-str_lib.o: str_lib.c str_locl.h
+str_lib.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+str_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+str_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+str_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+str_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+str_lib.o: ../../include/openssl/stack.h ../../include/openssl/store.h
+str_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+str_lib.o: ../../include/openssl/x509_vfy.h str_lib.c str_locl.h
 str_mem.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
 str_mem.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
 str_mem.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
diff --git a/crypto/symhacks.h b/crypto/symhacks.h
index 64528ad..8728e61 100644
--- a/crypto/symhacks.h
+++ b/crypto/symhacks.h
@@ -62,6 +62,10 @@
    VAX. */
 #ifdef OPENSSL_SYS_VMS
 
+/* Hack a long name in crypto/cryptlib.c */
+#undef int_CRYPTO_set_do_dynlock_callback
+#define int_CRYPTO_set_do_dynlock_callback	int_CRYPTO_set_do_dynlock_cb
+
 /* Hack a long name in crypto/ex_data.c */
 #undef CRYPTO_get_ex_data_implementation
 #define CRYPTO_get_ex_data_implementation	CRYPTO_get_ex_data_impl
@@ -179,6 +183,11 @@
 #define ENGINE_set_load_privkey_function        ENGINE_set_load_privkey_fn
 #undef ENGINE_get_load_privkey_function
 #define ENGINE_get_load_privkey_function        ENGINE_get_load_privkey_fn
+#undef ENGINE_set_load_ssl_client_cert_function
+#define ENGINE_set_load_ssl_client_cert_function \
+						ENGINE_set_ld_ssl_clnt_cert_fn
+#undef ENGINE_get_ssl_client_cert_function
+#define ENGINE_get_ssl_client_cert_function	ENGINE_get_ssl_client_cert_fn
 
 /* Hack some long OCSP names */
 #undef OCSP_REQUEST_get_ext_by_critical
diff --git a/crypto/txt_db/Makefile b/crypto/txt_db/Makefile
index e6f3033..87e57b4 100644
--- a/crypto/txt_db/Makefile
+++ b/crypto/txt_db/Makefile
@@ -33,7 +33,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
diff --git a/crypto/ui/Makefile b/crypto/ui/Makefile
index a685659..4755e20 100644
--- a/crypto/ui/Makefile
+++ b/crypto/ui/Makefile
@@ -37,7 +37,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
diff --git a/crypto/ui/ui_lib.c b/crypto/ui/ui_lib.c
index 7ab249c..ac01008 100644
--- a/crypto/ui/ui_lib.c
+++ b/crypto/ui/ui_lib.c
@@ -90,6 +90,7 @@
 
 	ret->strings=NULL;
 	ret->user_data=NULL;
+	ret->flags=0;
 	CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI, ret, &ret->ex_data);
 	return ret;
 	}
diff --git a/crypto/ui/ui_openssl.c b/crypto/ui/ui_openssl.c
index 1f23a45..ef930bf 100644
--- a/crypto/ui/ui_openssl.c
+++ b/crypto/ui/ui_openssl.c
@@ -677,6 +677,8 @@
 		size--;
 #ifdef WIN16TTY
 		i=_inchar();
+#elif defined(_WIN32)
+		i=_getch();
 #else
 		i=getch();
 #endif
diff --git a/crypto/x509/Makefile b/crypto/x509/Makefile
index ddcc312..464752b 100644
--- a/crypto/x509/Makefile
+++ b/crypto/x509/Makefile
@@ -43,7 +43,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -89,35 +89,37 @@
 by_dir.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 by_dir.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 by_dir.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-by_dir.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-by_dir.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-by_dir.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-by_dir.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-by_dir.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-by_dir.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-by_dir.o: ../../include/openssl/x509_vfy.h ../cryptlib.h by_dir.c
+by_dir.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+by_dir.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+by_dir.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+by_dir.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+by_dir.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+by_dir.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+by_dir.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+by_dir.o: ../cryptlib.h by_dir.c
 by_file.o: ../../e_os.h ../../include/openssl/asn1.h
 by_file.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 by_file.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 by_file.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 by_file.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-by_file.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-by_file.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-by_file.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-by_file.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
-by_file.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
-by_file.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-by_file.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-by_file.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-by_file.o: ../cryptlib.h by_file.c
+by_file.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+by_file.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+by_file.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+by_file.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+by_file.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
+by_file.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+by_file.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+by_file.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+by_file.o: ../../include/openssl/x509_vfy.h ../cryptlib.h by_file.c
 x509_att.o: ../../e_os.h ../../include/openssl/asn1.h
 x509_att.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 x509_att.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
 x509_att.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x509_att.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x509_att.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x509_att.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x509_att.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_att.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x509_att.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509_att.o: ../../include/openssl/opensslconf.h
 x509_att.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x509_att.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x509_att.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -130,8 +132,9 @@
 x509_cmp.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x509_cmp.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x509_cmp.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x509_cmp.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x509_cmp.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_cmp.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x509_cmp.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509_cmp.o: ../../include/openssl/opensslconf.h
 x509_cmp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x509_cmp.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x509_cmp.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -143,22 +146,22 @@
 x509_d2.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 x509_d2.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 x509_d2.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-x509_d2.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-x509_d2.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509_d2.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-x509_d2.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-x509_d2.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-x509_d2.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-x509_d2.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-x509_d2.o: ../cryptlib.h x509_d2.c
+x509_d2.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+x509_d2.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509_d2.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_d2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x509_d2.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+x509_d2.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+x509_d2.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+x509_d2.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x509_d2.c
 x509_def.o: ../../e_os.h ../../include/openssl/asn1.h
 x509_def.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 x509_def.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 x509_def.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 x509_def.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-x509_def.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-x509_def.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509_def.o: ../../include/openssl/opensslconf.h
+x509_def.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+x509_def.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509_def.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 x509_def.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x509_def.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x509_def.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -169,8 +172,9 @@
 x509_err.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x509_err.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x509_err.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x509_err.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x509_err.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_err.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x509_err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509_err.o: ../../include/openssl/opensslconf.h
 x509_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x509_err.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x509_err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -182,8 +186,9 @@
 x509_ext.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x509_ext.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x509_ext.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x509_ext.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x509_ext.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_ext.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x509_ext.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509_ext.o: ../../include/openssl/opensslconf.h
 x509_ext.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x509_ext.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x509_ext.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -196,22 +201,22 @@
 x509_lu.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x509_lu.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x509_lu.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x509_lu.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x509_lu.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-x509_lu.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-x509_lu.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-x509_lu.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-x509_lu.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509_lu.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-x509_lu.o: ../cryptlib.h x509_lu.c
+x509_lu.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x509_lu.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509_lu.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+x509_lu.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+x509_lu.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+x509_lu.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+x509_lu.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x509_lu.o: ../../include/openssl/x509v3.h ../cryptlib.h x509_lu.c
 x509_obj.o: ../../e_os.h ../../include/openssl/asn1.h
 x509_obj.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 x509_obj.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 x509_obj.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 x509_obj.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-x509_obj.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-x509_obj.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509_obj.o: ../../include/openssl/opensslconf.h
+x509_obj.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+x509_obj.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509_obj.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 x509_obj.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x509_obj.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x509_obj.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -223,8 +228,9 @@
 x509_r2x.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x509_r2x.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x509_r2x.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x509_r2x.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x509_r2x.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_r2x.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x509_r2x.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509_r2x.o: ../../include/openssl/opensslconf.h
 x509_r2x.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x509_r2x.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x509_r2x.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -236,8 +242,9 @@
 x509_req.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x509_req.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x509_req.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x509_req.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x509_req.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_req.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x509_req.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509_req.o: ../../include/openssl/opensslconf.h
 x509_req.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x509_req.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
 x509_req.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
@@ -249,9 +256,9 @@
 x509_set.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 x509_set.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 x509_set.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-x509_set.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-x509_set.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509_set.o: ../../include/openssl/opensslconf.h
+x509_set.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+x509_set.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509_set.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 x509_set.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x509_set.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x509_set.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -263,8 +270,9 @@
 x509_trs.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x509_trs.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x509_trs.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x509_trs.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x509_trs.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_trs.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x509_trs.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509_trs.o: ../../include/openssl/opensslconf.h
 x509_trs.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x509_trs.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x509_trs.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -276,9 +284,9 @@
 x509_txt.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 x509_txt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 x509_txt.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-x509_txt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-x509_txt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509_txt.o: ../../include/openssl/opensslconf.h
+x509_txt.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+x509_txt.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509_txt.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 x509_txt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x509_txt.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x509_txt.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -290,22 +298,23 @@
 x509_v3.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x509_v3.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x509_v3.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x509_v3.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x509_v3.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-x509_v3.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-x509_v3.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-x509_v3.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-x509_v3.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x509_v3.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-x509_v3.o: ../cryptlib.h x509_v3.c
+x509_v3.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x509_v3.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509_v3.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+x509_v3.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+x509_v3.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+x509_v3.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+x509_v3.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x509_v3.o: ../../include/openssl/x509v3.h ../cryptlib.h x509_v3.c
 x509_vfy.o: ../../e_os.h ../../include/openssl/asn1.h
 x509_vfy.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 x509_vfy.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
 x509_vfy.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x509_vfy.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x509_vfy.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x509_vfy.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x509_vfy.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_vfy.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x509_vfy.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509_vfy.o: ../../include/openssl/opensslconf.h
 x509_vfy.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x509_vfy.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x509_vfy.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -318,8 +327,9 @@
 x509_vpm.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 x509_vpm.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 x509_vpm.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-x509_vpm.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-x509_vpm.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x509_vpm.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+x509_vpm.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+x509_vpm.o: ../../include/openssl/opensslconf.h
 x509_vpm.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x509_vpm.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x509_vpm.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -331,9 +341,9 @@
 x509cset.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 x509cset.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 x509cset.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-x509cset.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-x509cset.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509cset.o: ../../include/openssl/opensslconf.h
+x509cset.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+x509cset.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509cset.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 x509cset.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x509cset.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x509cset.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -344,9 +354,9 @@
 x509name.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 x509name.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 x509name.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-x509name.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-x509name.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509name.o: ../../include/openssl/opensslconf.h
+x509name.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+x509name.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509name.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 x509name.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x509name.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x509name.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -357,9 +367,9 @@
 x509rset.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 x509rset.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 x509rset.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-x509rset.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-x509rset.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509rset.o: ../../include/openssl/opensslconf.h
+x509rset.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+x509rset.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509rset.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 x509rset.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x509rset.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x509rset.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -370,9 +380,9 @@
 x509spki.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 x509spki.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 x509spki.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-x509spki.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-x509spki.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509spki.o: ../../include/openssl/opensslconf.h
+x509spki.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+x509spki.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509spki.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 x509spki.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x509spki.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x509spki.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -383,9 +393,9 @@
 x509type.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 x509type.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 x509type.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-x509type.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-x509type.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x509type.o: ../../include/openssl/opensslconf.h
+x509type.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+x509type.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x509type.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 x509type.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 x509type.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 x509type.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -396,11 +406,12 @@
 x_all.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
 x_all.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 x_all.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-x_all.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-x_all.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-x_all.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-x_all.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-x_all.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-x_all.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-x_all.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-x_all.o: ../../include/openssl/x509_vfy.h ../cryptlib.h x_all.c
+x_all.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+x_all.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+x_all.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+x_all.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+x_all.o: ../../include/openssl/pkcs7.h ../../include/openssl/rsa.h
+x_all.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+x_all.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+x_all.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+x_all.o: ../cryptlib.h x_all.c
diff --git a/crypto/x509/by_dir.c b/crypto/x509/by_dir.c
index 37f9a48..341e0ba 100644
--- a/crypto/x509/by_dir.c
+++ b/crypto/x509/by_dir.c
@@ -74,6 +74,10 @@
 #include <openssl/lhash.h>
 #include <openssl/x509.h>
 
+#ifdef _WIN32
+#define stat	_stat
+#endif
+
 typedef struct lookup_dir_st
 	{
 	BUF_MEM *buffer;
diff --git a/crypto/x509/x509_att.c b/crypto/x509/x509_att.c
index 511b49d..98460e8 100644
--- a/crypto/x509/x509_att.c
+++ b/crypto/x509/x509_att.c
@@ -245,7 +245,7 @@
 		goto err;
 	if (!X509_ATTRIBUTE_set1_data(ret,atrtype,data,len))
 		goto err;
-	
+
 	if ((attr != NULL) && (*attr == NULL)) *attr=ret;
 	return(ret);
 err:
@@ -302,8 +302,15 @@
 		atype = attrtype;
 	}
 	if(!(attr->value.set = sk_ASN1_TYPE_new_null())) goto err;
+	attr->single = 0;
+	/* This is a bit naughty because the attribute should really have
+	 * at least one value but some types use and zero length SET and
+	 * require this.
+	 */
+	if (attrtype == 0)
+		return 1;
 	if(!(ttmp = ASN1_TYPE_new())) goto err;
-	if (len == -1)
+	if ((len == -1) && !(attrtype & MBSTRING_FLAG))
 		{
 		if (!ASN1_TYPE_set1(ttmp, attrtype, data))
 			goto err;
@@ -311,7 +318,6 @@
 	else
 		ASN1_TYPE_set(ttmp, atype, stmp);
 	if(!sk_ASN1_TYPE_push(attr->value.set, ttmp)) goto err;
-	attr->single = 0;
 	return 1;
 	err:
 	X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE);
diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c
index 0d6bc65..2faf925 100644
--- a/crypto/x509/x509_cmp.c
+++ b/crypto/x509/x509_cmp.c
@@ -288,7 +288,8 @@
 			if (!(nabit & STR_TYPE_CMP) ||
 				!(nbbit & STR_TYPE_CMP))
 				return j;
-			j = asn1_string_memcmp(na->value, nb->value);
+			if (!asn1_string_memcmp(na->value, nb->value))
+				j = 0;
 			}
 		else if (na->value->type == V_ASN1_PRINTABLESTRING)
 			j=nocase_spacenorm_cmp(na->value, nb->value);
@@ -322,10 +323,16 @@
 	{
 	unsigned long ret=0;
 	unsigned char md[16];
+	EVP_MD_CTX md_ctx;
 
 	/* Make sure X509_NAME structure contains valid cached encoding */
 	i2d_X509_NAME(x,NULL);
-	EVP_Digest(x->bytes->data, x->bytes->length, md, NULL, EVP_md5(), NULL);
+	EVP_MD_CTX_init(&md_ctx);
+	EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+	EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL);
+	EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length);
+	EVP_DigestFinal_ex(&md_ctx,md,NULL);
+	EVP_MD_CTX_cleanup(&md_ctx);
 
 	ret=(	((unsigned long)md[0]     )|((unsigned long)md[1]<<8L)|
 		((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
diff --git a/crypto/x509/x509_trs.c b/crypto/x509/x509_trs.c
index 9c84a59..ed18700 100644
--- a/crypto/x509/x509_trs.c
+++ b/crypto/x509/x509_trs.c
@@ -1,5 +1,5 @@
 /* x509_trs.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 9a62ebc..336c40d 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -394,7 +394,7 @@
 #ifdef OPENSSL_NO_CHAIN_VERIFY
 	return 1;
 #else
-	int i, ok=0, must_be_ca;
+	int i, ok=0, must_be_ca, plen = 0;
 	X509 *x;
 	int (*cb)(int xok,X509_STORE_CTX *xctx);
 	int proxy_path_length = 0;
@@ -495,9 +495,10 @@
 				if (!ok) goto end;
 				}
 			}
-		/* Check pathlen */
-		if ((i > 1) && (x->ex_pathlen != -1)
-			   && (i > (x->ex_pathlen + proxy_path_length + 1)))
+		/* Check pathlen if not self issued */
+		if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
+			   && (x->ex_pathlen != -1)
+			   && (plen > (x->ex_pathlen + proxy_path_length + 1)))
 			{
 			ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
 			ctx->error_depth = i;
@@ -505,6 +506,9 @@
 			ok=cb(0,ctx);
 			if (!ok) goto end;
 			}
+		/* Increment path length if not self issued */
+		if (!(x->ex_flags & EXFLAG_SI))
+			plen++;
 		/* If this certificate is a proxy certificate, the next
 		   certificate must be another proxy certificate or a EE
 		   certificate.  If not, the next certificate must be a
diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c
index e9db6d6..2b06718 100644
--- a/crypto/x509/x509_vpm.c
+++ b/crypto/x509/x509_vpm.c
@@ -1,5 +1,5 @@
 /* x509_vpm.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2004.
  */
 /* ====================================================================
@@ -74,7 +74,7 @@
 	param->name = NULL;
 	param->purpose = 0;
 	param->trust = 0;
-	param->inh_flags = X509_VP_FLAG_DEFAULT;
+	param->inh_flags = 0;
 	param->flags = 0;
 	param->depth = -1;
 	if (param->policies)
@@ -320,11 +320,21 @@
 	0,		/* flags */
 	0,		/* purpose */
 	0,		/* trust */
-	9,		/* depth */
+	100,		/* depth */
 	NULL		/* policies */
 	},
 	{
-	"pkcs7",			/* SSL/TLS client parameters */
+	"pkcs7",			/* S/MIME signing parameters */
+	0,				/* Check time */
+	0,				/* internal flags */
+	0,				/* flags */
+	X509_PURPOSE_SMIME_SIGN,	/* purpose */
+	X509_TRUST_EMAIL,		/* trust */
+	-1,				/* depth */
+	NULL				/* policies */
+	},
+	{
+	"smime_sign",			/* S/MIME signing parameters */
 	0,				/* Check time */
 	0,				/* internal flags */
 	0,				/* flags */
diff --git a/crypto/x509/x509cset.c b/crypto/x509/x509cset.c
index 9d1646d..7f4004b 100644
--- a/crypto/x509/x509cset.c
+++ b/crypto/x509/x509cset.c
@@ -1,5 +1,5 @@
 /* crypto/x509/x509cset.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2001.
  */
 /* ====================================================================
diff --git a/crypto/x509/x509spki.c b/crypto/x509/x509spki.c
index ed868b8..02a203d 100644
--- a/crypto/x509/x509spki.c
+++ b/crypto/x509/x509spki.c
@@ -1,5 +1,5 @@
 /* x509spki.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/Makefile b/crypto/x509v3/Makefile
index 556ef35..e71dc42 100644
--- a/crypto/x509v3/Makefile
+++ b/crypto/x509v3/Makefile
@@ -43,7 +43,7 @@
 all:	lib
 
 lib:	$(LIBOBJ)
-	$(AR) $(LIB) $(LIBOBJ)
+	$(ARX) $(LIB) $(LIBOBJ)
 	$(RANLIB) $(LIB) || echo Never mind.
 	@touch lib
 
@@ -90,8 +90,8 @@
 pcy_cache.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 pcy_cache.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 pcy_cache.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-pcy_cache.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-pcy_cache.o: ../../include/openssl/objects.h
+pcy_cache.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+pcy_cache.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
 pcy_cache.o: ../../include/openssl/opensslconf.h
 pcy_cache.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 pcy_cache.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
@@ -105,8 +105,9 @@
 pcy_data.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 pcy_data.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 pcy_data.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-pcy_data.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-pcy_data.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pcy_data.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+pcy_data.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pcy_data.o: ../../include/openssl/opensslconf.h
 pcy_data.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 pcy_data.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 pcy_data.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -119,35 +120,36 @@
 pcy_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 pcy_lib.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 pcy_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-pcy_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-pcy_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-pcy_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-pcy_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-pcy_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-pcy_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-pcy_lib.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-pcy_lib.o: ../cryptlib.h pcy_int.h pcy_lib.c
+pcy_lib.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+pcy_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pcy_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+pcy_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+pcy_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+pcy_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+pcy_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+pcy_lib.o: ../../include/openssl/x509v3.h ../cryptlib.h pcy_int.h pcy_lib.c
 pcy_map.o: ../../e_os.h ../../include/openssl/asn1.h
 pcy_map.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 pcy_map.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
 pcy_map.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 pcy_map.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 pcy_map.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-pcy_map.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-pcy_map.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-pcy_map.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-pcy_map.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-pcy_map.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-pcy_map.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-pcy_map.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-pcy_map.o: ../cryptlib.h pcy_int.h pcy_map.c
+pcy_map.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+pcy_map.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pcy_map.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+pcy_map.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+pcy_map.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+pcy_map.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+pcy_map.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+pcy_map.o: ../../include/openssl/x509v3.h ../cryptlib.h pcy_int.h pcy_map.c
 pcy_node.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 pcy_node.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
 pcy_node.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 pcy_node.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 pcy_node.o: ../../include/openssl/ecdsa.h ../../include/openssl/evp.h
-pcy_node.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-pcy_node.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pcy_node.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+pcy_node.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pcy_node.o: ../../include/openssl/opensslconf.h
 pcy_node.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 pcy_node.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 pcy_node.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -160,8 +162,9 @@
 pcy_tree.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 pcy_tree.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 pcy_tree.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-pcy_tree.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-pcy_tree.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+pcy_tree.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+pcy_tree.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+pcy_tree.o: ../../include/openssl/opensslconf.h
 pcy_tree.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 pcy_tree.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 pcy_tree.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -174,37 +177,39 @@
 v3_addr.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_addr.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_addr.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_addr.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_addr.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_addr.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-v3_addr.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-v3_addr.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-v3_addr.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-v3_addr.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-v3_addr.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_addr.c
+v3_addr.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_addr.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_addr.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_addr.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_addr.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_addr.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_addr.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_addr.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_addr.o: ../cryptlib.h v3_addr.c
 v3_akey.o: ../../e_os.h ../../include/openssl/asn1.h
 v3_akey.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 v3_akey.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
 v3_akey.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_akey.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_akey.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_akey.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_akey.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_akey.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-v3_akey.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-v3_akey.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-v3_akey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-v3_akey.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-v3_akey.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_akey.c
+v3_akey.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_akey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_akey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_akey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_akey.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_akey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_akey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_akey.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_akey.o: ../cryptlib.h v3_akey.c
 v3_akeya.o: ../../e_os.h ../../include/openssl/asn1.h
 v3_akeya.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 v3_akeya.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
 v3_akeya.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_akeya.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_akeya.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_akeya.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_akeya.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_akeya.o: ../../include/openssl/opensslconf.h
+v3_akeya.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_akeya.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_akeya.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 v3_akeya.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 v3_akeya.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 v3_akeya.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -216,14 +221,15 @@
 v3_alt.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_alt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_alt.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_alt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_alt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_alt.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-v3_alt.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-v3_alt.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-v3_alt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-v3_alt.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-v3_alt.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_alt.c
+v3_alt.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_alt.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_alt.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_alt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_alt.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_alt.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_alt.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_alt.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_alt.o: ../cryptlib.h v3_alt.c
 v3_asid.o: ../../e_os.h ../../include/openssl/asn1.h
 v3_asid.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 v3_asid.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
@@ -231,23 +237,23 @@
 v3_asid.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 v3_asid.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 v3_asid.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-v3_asid.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-v3_asid.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-v3_asid.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-v3_asid.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-v3_asid.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-v3_asid.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-v3_asid.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-v3_asid.o: ../cryptlib.h v3_asid.c
+v3_asid.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+v3_asid.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_asid.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_asid.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_asid.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_asid.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_asid.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_asid.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_asid.c
 v3_bcons.o: ../../e_os.h ../../include/openssl/asn1.h
 v3_bcons.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 v3_bcons.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
 v3_bcons.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_bcons.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_bcons.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_bcons.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_bcons.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_bcons.o: ../../include/openssl/opensslconf.h
+v3_bcons.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_bcons.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_bcons.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 v3_bcons.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 v3_bcons.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 v3_bcons.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -260,8 +266,9 @@
 v3_bitst.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 v3_bitst.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 v3_bitst.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-v3_bitst.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-v3_bitst.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_bitst.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+v3_bitst.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_bitst.o: ../../include/openssl/opensslconf.h
 v3_bitst.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 v3_bitst.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 v3_bitst.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -274,23 +281,23 @@
 v3_conf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 v3_conf.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 v3_conf.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-v3_conf.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-v3_conf.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-v3_conf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-v3_conf.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-v3_conf.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-v3_conf.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-v3_conf.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-v3_conf.o: ../cryptlib.h v3_conf.c
+v3_conf.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+v3_conf.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_conf.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_conf.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_conf.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_conf.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_conf.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_conf.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_conf.c
 v3_cpols.o: ../../e_os.h ../../include/openssl/asn1.h
 v3_cpols.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 v3_cpols.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
 v3_cpols.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_cpols.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_cpols.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_cpols.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_cpols.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_cpols.o: ../../include/openssl/opensslconf.h
+v3_cpols.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_cpols.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_cpols.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 v3_cpols.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 v3_cpols.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 v3_cpols.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -303,37 +310,38 @@
 v3_crld.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_crld.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_crld.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_crld.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_crld.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_crld.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-v3_crld.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-v3_crld.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-v3_crld.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-v3_crld.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-v3_crld.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_crld.c
+v3_crld.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_crld.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_crld.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_crld.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_crld.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_crld.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_crld.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_crld.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_crld.o: ../cryptlib.h v3_crld.c
 v3_enum.o: ../../e_os.h ../../include/openssl/asn1.h
 v3_enum.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 v3_enum.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
 v3_enum.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 v3_enum.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 v3_enum.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-v3_enum.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-v3_enum.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-v3_enum.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-v3_enum.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-v3_enum.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-v3_enum.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-v3_enum.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-v3_enum.o: ../cryptlib.h v3_enum.c
+v3_enum.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+v3_enum.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_enum.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_enum.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_enum.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_enum.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_enum.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_enum.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_enum.c
 v3_extku.o: ../../e_os.h ../../include/openssl/asn1.h
 v3_extku.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 v3_extku.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
 v3_extku.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_extku.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_extku.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_extku.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_extku.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_extku.o: ../../include/openssl/opensslconf.h
+v3_extku.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_extku.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_extku.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 v3_extku.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 v3_extku.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 v3_extku.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -346,76 +354,81 @@
 v3_genn.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_genn.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_genn.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_genn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_genn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_genn.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-v3_genn.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-v3_genn.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-v3_genn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-v3_genn.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-v3_genn.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_genn.c
+v3_genn.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_genn.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_genn.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_genn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_genn.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_genn.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_genn.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_genn.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_genn.o: ../cryptlib.h v3_genn.c
 v3_ia5.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 v3_ia5.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
 v3_ia5.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_ia5.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_ia5.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_ia5.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_ia5.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_ia5.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-v3_ia5.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-v3_ia5.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-v3_ia5.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-v3_ia5.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-v3_ia5.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_ia5.c
+v3_ia5.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_ia5.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_ia5.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_ia5.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_ia5.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_ia5.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_ia5.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_ia5.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_ia5.o: ../cryptlib.h v3_ia5.c
 v3_info.o: ../../e_os.h ../../include/openssl/asn1.h
 v3_info.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 v3_info.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
 v3_info.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_info.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_info.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_info.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_info.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_info.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-v3_info.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-v3_info.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-v3_info.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-v3_info.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-v3_info.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_info.c
+v3_info.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_info.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_info.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_info.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_info.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_info.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_info.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_info.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_info.o: ../cryptlib.h v3_info.c
 v3_int.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 v3_int.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
 v3_int.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_int.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_int.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_int.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_int.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_int.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-v3_int.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-v3_int.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-v3_int.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-v3_int.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-v3_int.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_int.c
+v3_int.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_int.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_int.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_int.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_int.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_int.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_int.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_int.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_int.o: ../cryptlib.h v3_int.c
 v3_lib.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 v3_lib.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
 v3_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-v3_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-v3_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-v3_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-v3_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-v3_lib.o: ../../include/openssl/x509v3.h ../cryptlib.h ext_dat.h v3_lib.c
+v3_lib.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_lib.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_lib.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_lib.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_lib.o: ../cryptlib.h ext_dat.h v3_lib.c
 v3_ncons.o: ../../e_os.h ../../include/openssl/asn1.h
 v3_ncons.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 v3_ncons.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
 v3_ncons.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_ncons.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_ncons.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_ncons.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_ncons.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_ncons.o: ../../include/openssl/opensslconf.h
+v3_ncons.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_ncons.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_ncons.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 v3_ncons.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 v3_ncons.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 v3_ncons.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -428,49 +441,52 @@
 v3_ocsp.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 v3_ocsp.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 v3_ocsp.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-v3_ocsp.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-v3_ocsp.o: ../../include/openssl/objects.h ../../include/openssl/ocsp.h
-v3_ocsp.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-v3_ocsp.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-v3_ocsp.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-v3_ocsp.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-v3_ocsp.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-v3_ocsp.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_ocsp.c
+v3_ocsp.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+v3_ocsp.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_ocsp.o: ../../include/openssl/ocsp.h ../../include/openssl/opensslconf.h
+v3_ocsp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_ocsp.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_ocsp.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_ocsp.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_ocsp.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_ocsp.o: ../cryptlib.h v3_ocsp.c
 v3_pci.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
 v3_pci.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
 v3_pci.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_pci.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_pci.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_pci.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_pci.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_pci.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-v3_pci.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-v3_pci.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-v3_pci.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-v3_pci.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-v3_pci.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_pci.c
+v3_pci.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_pci.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_pci.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_pci.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_pci.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_pci.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_pci.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_pci.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_pci.o: ../cryptlib.h v3_pci.c
 v3_pcia.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
 v3_pcia.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 v3_pcia.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
 v3_pcia.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 v3_pcia.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
-v3_pcia.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_pcia.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_pcia.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-v3_pcia.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-v3_pcia.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-v3_pcia.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-v3_pcia.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-v3_pcia.o: ../../include/openssl/x509v3.h v3_pcia.c
+v3_pcia.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_pcia.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_pcia.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_pcia.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_pcia.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_pcia.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_pcia.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_pcia.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_pcia.o: v3_pcia.c
 v3_pcons.o: ../../e_os.h ../../include/openssl/asn1.h
 v3_pcons.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 v3_pcons.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
 v3_pcons.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_pcons.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_pcons.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_pcons.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_pcons.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_pcons.o: ../../include/openssl/opensslconf.h
+v3_pcons.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_pcons.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_pcons.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 v3_pcons.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 v3_pcons.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 v3_pcons.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -483,23 +499,24 @@
 v3_pku.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_pku.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_pku.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_pku.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_pku.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_pku.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-v3_pku.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-v3_pku.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-v3_pku.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-v3_pku.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-v3_pku.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_pku.c
+v3_pku.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_pku.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_pku.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_pku.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_pku.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_pku.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_pku.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_pku.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_pku.o: ../cryptlib.h v3_pku.c
 v3_pmaps.o: ../../e_os.h ../../include/openssl/asn1.h
 v3_pmaps.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 v3_pmaps.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
 v3_pmaps.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_pmaps.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_pmaps.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_pmaps.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_pmaps.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_pmaps.o: ../../include/openssl/opensslconf.h
+v3_pmaps.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_pmaps.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_pmaps.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 v3_pmaps.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 v3_pmaps.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 v3_pmaps.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -511,51 +528,52 @@
 v3_prn.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_prn.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_prn.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_prn.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_prn.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_prn.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-v3_prn.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-v3_prn.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-v3_prn.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-v3_prn.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-v3_prn.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_prn.c
+v3_prn.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_prn.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_prn.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3_prn.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3_prn.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3_prn.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3_prn.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3_prn.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3_prn.o: ../cryptlib.h v3_prn.c
 v3_purp.o: ../../e_os.h ../../include/openssl/asn1.h
 v3_purp.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 v3_purp.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
 v3_purp.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 v3_purp.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 v3_purp.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-v3_purp.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-v3_purp.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-v3_purp.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-v3_purp.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-v3_purp.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-v3_purp.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-v3_purp.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-v3_purp.o: ../cryptlib.h v3_purp.c
+v3_purp.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+v3_purp.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_purp.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_purp.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_purp.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_purp.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_purp.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_purp.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_purp.c
 v3_skey.o: ../../e_os.h ../../include/openssl/asn1.h
 v3_skey.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
 v3_skey.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
 v3_skey.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 v3_skey.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 v3_skey.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-v3_skey.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-v3_skey.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-v3_skey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-v3_skey.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-v3_skey.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-v3_skey.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-v3_skey.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-v3_skey.o: ../cryptlib.h v3_skey.c
+v3_skey.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+v3_skey.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_skey.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_skey.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_skey.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_skey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_skey.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_skey.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_skey.c
 v3_sxnet.o: ../../e_os.h ../../include/openssl/asn1.h
 v3_sxnet.o: ../../include/openssl/asn1t.h ../../include/openssl/bio.h
 v3_sxnet.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
 v3_sxnet.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3_sxnet.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3_sxnet.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3_sxnet.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3_sxnet.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3_sxnet.o: ../../include/openssl/opensslconf.h
+v3_sxnet.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3_sxnet.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3_sxnet.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
 v3_sxnet.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
 v3_sxnet.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
 v3_sxnet.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
@@ -568,24 +586,25 @@
 v3_utl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
 v3_utl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
 v3_utl.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-v3_utl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-v3_utl.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
-v3_utl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-v3_utl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
-v3_utl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-v3_utl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-v3_utl.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
-v3_utl.o: ../cryptlib.h v3_utl.c
+v3_utl.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
+v3_utl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+v3_utl.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+v3_utl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
+v3_utl.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+v3_utl.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+v3_utl.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+v3_utl.o: ../../include/openssl/x509v3.h ../cryptlib.h v3_utl.c
 v3err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
 v3err.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h
 v3err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
 v3err.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
 v3err.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-v3err.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
-v3err.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-v3err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
-v3err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-v3err.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-v3err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-v3err.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-v3err.o: ../../include/openssl/x509v3.h v3err.c
+v3err.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+v3err.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
+v3err.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
+v3err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+v3err.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
+v3err.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
+v3err.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+v3err.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
+v3err.o: v3err.c
diff --git a/crypto/x509v3/ext_dat.h b/crypto/x509v3/ext_dat.h
index 5c063ac..3eaec46 100644
--- a/crypto/x509v3/ext_dat.h
+++ b/crypto/x509v3/ext_dat.h
@@ -1,5 +1,5 @@
 /* ext_dat.h */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/pcy_cache.c b/crypto/x509v3/pcy_cache.c
index c18beb8..1030931 100644
--- a/crypto/x509v3/pcy_cache.c
+++ b/crypto/x509v3/pcy_cache.c
@@ -1,5 +1,5 @@
 /* pcy_cache.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2004.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/pcy_data.c b/crypto/x509v3/pcy_data.c
index 614d2b4..fb392b9 100644
--- a/crypto/x509v3/pcy_data.c
+++ b/crypto/x509v3/pcy_data.c
@@ -1,5 +1,5 @@
 /* pcy_data.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2004.
  */
 /* ====================================================================
@@ -87,6 +87,12 @@
 	X509_POLICY_DATA *ret;
 	if (!policy && !id)
 		return NULL;
+	if (id)
+		{
+		id = OBJ_dup(id);
+		if (!id)
+			return NULL;
+		}
 	ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA));
 	if (!ret)
 		return NULL;
@@ -94,6 +100,8 @@
 	if (!ret->expected_policy_set)
 		{
 		OPENSSL_free(ret);
+		if (id)
+			ASN1_OBJECT_free(id);
 		return NULL;
 		}
 
diff --git a/crypto/x509v3/pcy_int.h b/crypto/x509v3/pcy_int.h
index ba62a20..3780de4 100644
--- a/crypto/x509v3/pcy_int.h
+++ b/crypto/x509v3/pcy_int.h
@@ -1,5 +1,5 @@
 /* pcy_int.h */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2004.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/pcy_lib.c b/crypto/x509v3/pcy_lib.c
index dae4840..93bfd92 100644
--- a/crypto/x509v3/pcy_lib.c
+++ b/crypto/x509v3/pcy_lib.c
@@ -1,5 +1,5 @@
 /* pcy_lib.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2004.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/pcy_map.c b/crypto/x509v3/pcy_map.c
index 35221e8..f28796e 100644
--- a/crypto/x509v3/pcy_map.c
+++ b/crypto/x509v3/pcy_map.c
@@ -1,5 +1,5 @@
 /* pcy_map.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2004.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/pcy_node.c b/crypto/x509v3/pcy_node.c
index dcc1554..6587cb0 100644
--- a/crypto/x509v3/pcy_node.c
+++ b/crypto/x509v3/pcy_node.c
@@ -1,5 +1,5 @@
 /* pcy_node.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2004.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/pcy_tree.c b/crypto/x509v3/pcy_tree.c
index 4fda1d4..6c87a7f 100644
--- a/crypto/x509v3/pcy_tree.c
+++ b/crypto/x509v3/pcy_tree.c
@@ -1,5 +1,5 @@
 /* pcy_tree.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2004.
  */
 /* ====================================================================
@@ -130,9 +130,9 @@
 			ret = 2;
 		if (explicit_policy > 0)
 			{
-			explicit_policy--;
-			if (!(x->ex_flags & EXFLAG_SS)
-				&& (cache->explicit_skip != -1)
+			if (!(x->ex_flags & EXFLAG_SI))
+				explicit_policy--;
+			if ((cache->explicit_skip != -1)
 				&& (cache->explicit_skip < explicit_policy))
 				explicit_policy = cache->explicit_skip;
 			}
@@ -197,13 +197,14 @@
 			/* Any matching allowed if certificate is self
 			 * issued and not the last in the chain.
 			 */
-			if (!(x->ex_flags & EXFLAG_SS) || (i == 0))
+			if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
 				level->flags |= X509_V_FLAG_INHIBIT_ANY;
 			}
 		else
 			{
-			any_skip--;
-			if ((cache->any_skip > 0)
+			if (!(x->ex_flags & EXFLAG_SI))
+				any_skip--;
+			if ((cache->any_skip >= 0)
 				&& (cache->any_skip < any_skip))
 				any_skip = cache->any_skip;
 			}
@@ -213,7 +214,7 @@
 		else
 			{
 			map_skip--;
-			if ((cache->map_skip > 0)
+			if ((cache->map_skip >= 0)
 				&& (cache->map_skip < map_skip))
 				map_skip = cache->map_skip;
 			}
@@ -310,7 +311,8 @@
 
 		if (data == NULL)
 			return 0;
-		data->qualifier_set = curr->anyPolicy->data->qualifier_set;
+		/* Curr may not have anyPolicy */
+		data->qualifier_set = cache->anyPolicy->qualifier_set;
 		data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
 		if (!level_add_node(curr, data, node, tree))
 			{
diff --git a/crypto/x509v3/tabtest.c b/crypto/x509v3/tabtest.c
index dad0d38..5ed6eb6 100644
--- a/crypto/x509v3/tabtest.c
+++ b/crypto/x509v3/tabtest.c
@@ -1,5 +1,5 @@
 /* tabtest.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_addr.c b/crypto/x509v3/v3_addr.c
index ed9847b..efdf7c3 100644
--- a/crypto/x509v3/v3_addr.c
+++ b/crypto/x509v3/v3_addr.c
@@ -61,7 +61,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <assert.h>
+
 #include "cryptlib.h"
 #include <openssl/conf.h>
 #include <openssl/asn1.h>
@@ -128,7 +128,7 @@
 /*
  * Extract the AFI from an IPAddressFamily.
  */
-unsigned v3_addr_get_afi(const IPAddressFamily *f)
+unsigned int v3_addr_get_afi(const IPAddressFamily *f)
 {
   return ((f != NULL &&
 	   f->addressFamily != NULL &&
@@ -147,7 +147,7 @@
 			const int length,
 			const unsigned char fill)
 {
-  assert(bs->length >= 0 && bs->length <= length);
+  OPENSSL_assert(bs->length >= 0 && bs->length <= length);
   if (bs->length > 0) {
     memcpy(addr, bs->data, bs->length);
     if ((bs->flags & 7) != 0) {
@@ -190,6 +190,8 @@
       BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i+1], (i < 14 ? ":" : ""));
     if (i < 16)
       BIO_puts(out, ":");
+    if (i == 0)
+      BIO_puts(out, ":");
     break;
   default:
     for (i = 0; i < bs->length; i++)
@@ -243,7 +245,7 @@
   int i;
   for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
     IPAddressFamily *f = sk_IPAddressFamily_value(addr, i);
-    const unsigned afi = v3_addr_get_afi(f);
+    const unsigned int afi = v3_addr_get_afi(f);
     switch (afi) {
     case IANA_AFI_IPV4:
       BIO_printf(out, "%*sIPv4", indent, "");
@@ -453,7 +455,7 @@
   if ((aor = IPAddressOrRange_new()) == NULL)
     return 0;
   aor->type = IPAddressOrRange_addressRange;
-  assert(aor->u.addressRange == NULL);
+  OPENSSL_assert(aor->u.addressRange == NULL);
   if ((aor->u.addressRange = IPAddressRange_new()) == NULL)
     goto err;
   if (aor->u.addressRange->min == NULL &&
@@ -522,7 +524,7 @@
 
   for (i = 0; i < sk_IPAddressFamily_num(addr); i++) {
     f = sk_IPAddressFamily_value(addr, i);
-    assert(f->addressFamily->data != NULL);
+    OPENSSL_assert(f->addressFamily->data != NULL);
     if (f->addressFamily->length == keylen &&
 	!memcmp(f->addressFamily->data, key, keylen))
       return f;
@@ -594,10 +596,10 @@
     return NULL;
   switch (afi) {
   case IANA_AFI_IPV4:
-    sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);
+    (void)sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);
     break;
   case IANA_AFI_IPV6:
-    sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp);
+    (void)sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp);
     break;
   }
   f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges;
@@ -654,7 +656,7 @@
 			    unsigned char *max,
 			    int length)
 {
-  assert(aor != NULL && min != NULL && max != NULL);
+  OPENSSL_assert(aor != NULL && min != NULL && max != NULL);
   switch (aor->type) {
   case IPAddressOrRange_addressPrefix:
     addr_expand(min, aor->u.addressPrefix, length, 0x00);
@@ -854,7 +856,7 @@
       if (!make_addressRange(&merged, a_min, b_max, length))
 	return 0;
       sk_IPAddressOrRange_set(aors, i, merged);
-      sk_IPAddressOrRange_delete(aors, i + 1);
+      (void)sk_IPAddressOrRange_delete(aors, i + 1);
       IPAddressOrRange_free(a);
       IPAddressOrRange_free(b);
       --i;
@@ -878,8 +880,9 @@
 				    v3_addr_get_afi(f)))
       return 0;
   }
+  (void)sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp);
   sk_IPAddressFamily_sort(addr);
-  assert(v3_addr_is_canonical(addr));
+  OPENSSL_assert(v3_addr_is_canonical(addr));
   return 1;
 }
 
@@ -1122,11 +1125,14 @@
     return 1;
   if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b))
     return 0;
-  sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp);
+  (void)sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp);
   for (i = 0; i < sk_IPAddressFamily_num(a); i++) {
     IPAddressFamily *fa = sk_IPAddressFamily_value(a, i);
     int j = sk_IPAddressFamily_find(b, fa);
-    IPAddressFamily *fb = sk_IPAddressFamily_value(b, j);
+    IPAddressFamily *fb;
+    fb = sk_IPAddressFamily_value(b, j);
+    if (fb == NULL)
+       return 0;
     if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges, 
 		       fa->ipAddressChoice->u.addressesOrRanges,
 		       length_from_afi(v3_addr_get_afi(fb))))
@@ -1163,9 +1169,9 @@
   int i, j, ret = 1;
   X509 *x = NULL;
 
-  assert(chain != NULL && sk_X509_num(chain) > 0);
-  assert(ctx != NULL || ext != NULL);
-  assert(ctx == NULL || ctx->verify_cb != NULL);
+  OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0);
+  OPENSSL_assert(ctx != NULL || ext != NULL);
+  OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL);
 
   /*
    * Figure out where to start.  If we don't have an extension to
@@ -1177,13 +1183,13 @@
   } else {
     i = 0;
     x = sk_X509_value(chain, i);
-    assert(x != NULL);
+    OPENSSL_assert(x != NULL);
     if ((ext = x->rfc3779_addr) == NULL)
       goto done;
   }
   if (!v3_addr_is_canonical(ext))
     validation_err(X509_V_ERR_INVALID_EXTENSION);
-  sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp);
+  (void)sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp);
   if ((child = sk_IPAddressFamily_dup(ext)) == NULL) {
     X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, ERR_R_MALLOC_FAILURE);
     ret = 0;
@@ -1196,7 +1202,7 @@
    */
   for (i++; i < sk_X509_num(chain); i++) {
     x = sk_X509_value(chain, i);
-    assert(x != NULL);
+    OPENSSL_assert(x != NULL);
     if (!v3_addr_is_canonical(x->rfc3779_addr))
       validation_err(X509_V_ERR_INVALID_EXTENSION);
     if (x->rfc3779_addr == NULL) {
@@ -1209,7 +1215,7 @@
       }
       continue;
     }
-    sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp);
+    (void)sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp);
     for (j = 0; j < sk_IPAddressFamily_num(child); j++) {
       IPAddressFamily *fc = sk_IPAddressFamily_value(child, j);
       int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc);
diff --git a/crypto/x509v3/v3_akey.c b/crypto/x509v3/v3_akey.c
index ac0548b..c6b68ee 100644
--- a/crypto/x509v3/v3_akey.c
+++ b/crypto/x509v3/v3_akey.c
@@ -1,5 +1,5 @@
 /* v3_akey.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_akeya.c b/crypto/x509v3/v3_akeya.c
index 2aafa26..2c50f73 100644
--- a/crypto/x509v3/v3_akeya.c
+++ b/crypto/x509v3/v3_akeya.c
@@ -1,5 +1,5 @@
 /* v3_akey_asn1.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_alt.c b/crypto/x509v3/v3_alt.c
index bb2f5bc..58b2952 100644
--- a/crypto/x509v3/v3_alt.c
+++ b/crypto/x509v3/v3_alt.c
@@ -1,5 +1,5 @@
 /* v3_alt.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project.
  */
 /* ====================================================================
@@ -527,7 +527,8 @@
 	return gen;
 
 	err:
-	GENERAL_NAME_free(gen);
+	if (!out)
+		GENERAL_NAME_free(gen);
 	return NULL;
 	}
 
diff --git a/crypto/x509v3/v3_asid.c b/crypto/x509v3/v3_asid.c
index 271930f..abd497e 100644
--- a/crypto/x509v3/v3_asid.c
+++ b/crypto/x509v3/v3_asid.c
@@ -466,7 +466,7 @@
 	break;
       }
       ASIdOrRange_free(b);
-      sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1);
+      (void)sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1);
       i--;
       continue;
     }
diff --git a/crypto/x509v3/v3_bcons.c b/crypto/x509v3/v3_bcons.c
index 74b1233..82aa488 100644
--- a/crypto/x509v3/v3_bcons.c
+++ b/crypto/x509v3/v3_bcons.c
@@ -1,5 +1,5 @@
 /* v3_bcons.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_bitst.c b/crypto/x509v3/v3_bitst.c
index cf31f08..058d0d4 100644
--- a/crypto/x509v3/v3_bitst.c
+++ b/crypto/x509v3/v3_bitst.c
@@ -1,5 +1,5 @@
 /* v3_bitst.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_conf.c b/crypto/x509v3/v3_conf.c
index 2b86730..11eb6b7 100644
--- a/crypto/x509v3/v3_conf.c
+++ b/crypto/x509v3/v3_conf.c
@@ -1,5 +1,5 @@
 /* v3_conf.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_cpols.c b/crypto/x509v3/v3_cpols.c
index a40f490..ad0506d 100644
--- a/crypto/x509v3/v3_cpols.c
+++ b/crypto/x509v3/v3_cpols.c
@@ -1,5 +1,5 @@
 /* v3_cpols.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
@@ -181,7 +181,11 @@
 			pol = POLICYINFO_new();
 			pol->policyid = pobj;
 		}
-		sk_POLICYINFO_push(pols, pol);
+		if (!sk_POLICYINFO_push(pols, pol)){
+			POLICYINFO_free(pol);
+			X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE);
+			goto err;
+		}
 	}
 	sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
 	return pols;
@@ -447,3 +451,4 @@
 		BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, "");
 	}
 	
+IMPLEMENT_STACK_OF(X509_POLICY_NODE)
diff --git a/crypto/x509v3/v3_crld.c b/crypto/x509v3/v3_crld.c
index c6e3eba..181a897 100644
--- a/crypto/x509v3/v3_crld.c
+++ b/crypto/x509v3/v3_crld.c
@@ -1,5 +1,5 @@
 /* v3_crld.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_enum.c b/crypto/x509v3/v3_enum.c
index a236cb2..36576ea 100644
--- a/crypto/x509v3/v3_enum.c
+++ b/crypto/x509v3/v3_enum.c
@@ -1,5 +1,5 @@
 /* v3_enum.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_extku.c b/crypto/x509v3/v3_extku.c
index a4efe00..c0d1450 100644
--- a/crypto/x509v3/v3_extku.c
+++ b/crypto/x509v3/v3_extku.c
@@ -1,5 +1,5 @@
 /* v3_extku.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_genn.c b/crypto/x509v3/v3_genn.c
index 650b510..84b4b1c 100644
--- a/crypto/x509v3/v3_genn.c
+++ b/crypto/x509v3/v3_genn.c
@@ -1,5 +1,5 @@
 /* v3_genn.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_ia5.c b/crypto/x509v3/v3_ia5.c
index b739ccd..4ff12b5 100644
--- a/crypto/x509v3/v3_ia5.c
+++ b/crypto/x509v3/v3_ia5.c
@@ -1,5 +1,5 @@
 /* v3_ia5.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_info.c b/crypto/x509v3/v3_info.c
index e0ef69d..e1b8699 100644
--- a/crypto/x509v3/v3_info.c
+++ b/crypto/x509v3/v3_info.c
@@ -1,5 +1,5 @@
 /* v3_info.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_int.c b/crypto/x509v3/v3_int.c
index 9a48dc1..4bfd14c 100644
--- a/crypto/x509v3/v3_int.c
+++ b/crypto/x509v3/v3_int.c
@@ -1,5 +1,5 @@
 /* v3_int.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_lib.c b/crypto/x509v3/v3_lib.c
index f3015ea..df3a48f 100644
--- a/crypto/x509v3/v3_lib.c
+++ b/crypto/x509v3/v3_lib.c
@@ -1,5 +1,5 @@
 /* v3_lib.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_ncons.c b/crypto/x509v3/v3_ncons.c
index 42e7f5a..4e706be 100644
--- a/crypto/x509v3/v3_ncons.c
+++ b/crypto/x509v3/v3_ncons.c
@@ -1,5 +1,5 @@
 /* v3_ncons.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_ocsp.c b/crypto/x509v3/v3_ocsp.c
index 62aac06..e426ea9 100644
--- a/crypto/x509v3/v3_ocsp.c
+++ b/crypto/x509v3/v3_ocsp.c
@@ -1,5 +1,5 @@
 /* v3_ocsp.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_pcons.c b/crypto/x509v3/v3_pcons.c
index 13248c2..86c0ff7 100644
--- a/crypto/x509v3/v3_pcons.c
+++ b/crypto/x509v3/v3_pcons.c
@@ -1,5 +1,5 @@
 /* v3_pcons.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_pku.c b/crypto/x509v3/v3_pku.c
index 5c4626e..076f3ff 100644
--- a/crypto/x509v3/v3_pku.c
+++ b/crypto/x509v3/v3_pku.c
@@ -1,5 +1,5 @@
 /* v3_pku.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_pmaps.c b/crypto/x509v3/v3_pmaps.c
index 6263032..da03bbc 100644
--- a/crypto/x509v3/v3_pmaps.c
+++ b/crypto/x509v3/v3_pmaps.c
@@ -1,5 +1,5 @@
 /* v3_pmaps.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_prn.c b/crypto/x509v3/v3_prn.c
index 20bd9bd..c1bb17f 100644
--- a/crypto/x509v3/v3_prn.c
+++ b/crypto/x509v3/v3_prn.c
@@ -1,5 +1,5 @@
 /* v3_prn.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_purp.c b/crypto/x509v3/v3_purp.c
index b2f5cdf..e18751e 100644
--- a/crypto/x509v3/v3_purp.c
+++ b/crypto/x509v3/v3_purp.c
@@ -1,5 +1,5 @@
 /* v3_purp.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2001.
  */
 /* ====================================================================
@@ -291,7 +291,9 @@
 		NID_sbgp_ipAddrBlock,	/* 290 */
 		NID_sbgp_autonomousSysNum, /* 291 */
 #endif
-		NID_proxyCertInfo	/* 661 */
+		NID_policy_constraints,	/* 401 */
+		NID_proxyCertInfo,	/* 661 */
+		NID_inhibit_any_policy	/* 748 */
 	};
 
 	int ex_nid;
@@ -325,7 +327,7 @@
 #endif
 	/* Does subject name match issuer ? */
 	if(!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x)))
-			 x->ex_flags |= EXFLAG_SS;
+			 x->ex_flags |= EXFLAG_SI;
 	/* V1 should mean no extensions ... */
 	if(!X509_get_version(x)) x->ex_flags |= EXFLAG_V1;
 	/* Handle basic constraints */
diff --git a/crypto/x509v3/v3_skey.c b/crypto/x509v3/v3_skey.c
index da0a355..202c9e4 100644
--- a/crypto/x509v3/v3_skey.c
+++ b/crypto/x509v3/v3_skey.c
@@ -1,5 +1,5 @@
 /* v3_skey.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_sxnet.c b/crypto/x509v3/v3_sxnet.c
index eaea9ea..2a6bf11 100644
--- a/crypto/x509v3/v3_sxnet.c
+++ b/crypto/x509v3/v3_sxnet.c
@@ -1,5 +1,5 @@
 /* v3_sxnet.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3_utl.c b/crypto/x509v3/v3_utl.c
index ac171ca..7a45216 100644
--- a/crypto/x509v3/v3_utl.c
+++ b/crypto/x509v3/v3_utl.c
@@ -1,5 +1,5 @@
 /* v3_utl.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project.
  */
 /* ====================================================================
@@ -84,7 +84,7 @@
 	CONF_VALUE *vtmp = NULL;
 	char *tname = NULL, *tvalue = NULL;
 	if(name && !(tname = BUF_strdup(name))) goto err;
-	if(value && !(tvalue = BUF_strdup(value))) goto err;;
+	if(value && !(tvalue = BUF_strdup(value))) goto err;
 	if(!(vtmp = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) goto err;
 	if(!*extlist && !(*extlist = sk_CONF_VALUE_new_null())) goto err;
 	vtmp->section = NULL;
@@ -736,17 +736,20 @@
 
 	/* Format result */
 
-	/* Copy initial part */
-	if (v6stat.zero_pos > 0)
+	if (v6stat.zero_pos >= 0)
+		{
+		/* Copy initial part */
 		memcpy(v6, v6stat.tmp, v6stat.zero_pos);
-	/* Zero middle */
-	if (v6stat.total != 16)
+		/* Zero middle */
 		memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total);
-	/* Copy final part */
-	if (v6stat.total != v6stat.zero_pos)
-		memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
-			v6stat.tmp + v6stat.zero_pos,
-			v6stat.total - v6stat.zero_pos);
+		/* Copy final part */
+		if (v6stat.total != v6stat.zero_pos)
+			memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total,
+				v6stat.tmp + v6stat.zero_pos,
+				v6stat.total - v6stat.zero_pos);
+		}
+	else
+		memcpy(v6, v6stat.tmp, 16);
 
 	return 1;
 	}
diff --git a/crypto/x509v3/v3conf.c b/crypto/x509v3/v3conf.c
index 00cf5b4..a9e6ca3 100644
--- a/crypto/x509v3/v3conf.c
+++ b/crypto/x509v3/v3conf.c
@@ -1,5 +1,5 @@
 /* v3conf.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/v3prin.c b/crypto/x509v3/v3prin.c
index b529814..d5ff268 100644
--- a/crypto/x509v3/v3prin.c
+++ b/crypto/x509v3/v3prin.c
@@ -1,5 +1,5 @@
 /* v3prin.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/crypto/x509v3/x509v3.h b/crypto/x509v3/x509v3.h
index db2b048..9ef83da 100644
--- a/crypto/x509v3/x509v3.h
+++ b/crypto/x509v3/x509v3.h
@@ -1,5 +1,5 @@
 /* x509v3.h */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
@@ -363,6 +363,8 @@
 #define EXFLAG_NSCERT		0x8
 
 #define EXFLAG_CA		0x10
+/* Really self issued not necessarily self signed */
+#define EXFLAG_SI		0x20
 #define EXFLAG_SS		0x20
 #define EXFLAG_V1		0x40
 #define EXFLAG_INVALID		0x80
@@ -370,7 +372,7 @@
 #define EXFLAG_CRITICAL		0x200
 #define EXFLAG_PROXY		0x400
 
-#define EXFLAG_INVALID_POLICY	0x400
+#define EXFLAG_INVALID_POLICY	0x800
 
 #define KU_DIGITAL_SIGNATURE	0x0080
 #define KU_NON_REPUDIATION	0x0040