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/README.android b/README.android
index d35caa4..cf476f2 100644
--- a/README.android
+++ b/README.android
@@ -1,144 +1,41 @@
-Version Information
+OpenSSL on the Android platform.
 ---
 
-The code in this directory is based on 0.9.8h with patches from
-http://openssl.org/news/secadv_20090107.txt, and some backported OpenSSL code
-in crypto/0.9.9-dev.
+The code in this directory is based on $OPENSSL_VERSION in the file
+openssl.config, and some backported OpenSSL code in crypto/0.9.9-dev.
 
-
-Porting New Versions of OpenSSL
----
+Porting New Versions of OpenSSL.
+--
 
 The following steps are recommended for porting new OpenSSL versions.
 
+1) Retrieve the appropriate version of the OpenSSL source from
+   www.openssl.org/source (in tar.gz format)
 
-a) Run "./Configure linux-generic32 no-idea no-bf no-cast no-seed no-md2      \
-       -DL_ENDIAN"
-   in the openssl distribution directory.
+2) Update the variables in openssl.config as appropriate
 
-   (Ignore when the Configure scripts asks you to run "make depend".)
+3) Run ./import_openssl.sh openssl-*.tar.gz
+
+4) If there are any errors, then modify openssl.config, openssl.version
+   and patches in patches/ as appropriate.  Repeat step 3.
+
+5) From the root of the android source tree, build openssl.  For
+   example, on the dream platform, run make
+   out/target/product/dream/obj/EXECUTABLES/openssl_intermediates/LINKED/openssl
+
+   If there are build errors, then patches/*.mk, openssl.config, or
+   android-config.mk may need updating.
 
 
-b) Create an updated android-config.mk file by looking at CFLAG and DEPFLAG in
-   the Makefile resulting from step a.  Make sure to add all the -D flags to
-   LOCAL_CFLAGS, except -DTERMIO; include -DOPENSSL_NO_HW in addition to these.
+Optionally, check whether build flags (located in android-config.mk
+need to be updated.  Doing this step will help ensure that the
+compiled library is appropriately optimized for speed and size.  To
+update build flags:
 
-   (New OpenSSL releases may include additional code meant to be disabled by
-   default, so it's important not to miss any -DOPENSSL_NO_foo.
-   Usually these should be replicated in crypto/opensslconf.h, but let's not
-   take a chance.)
+a) source openssl.config
+b) tar -zxf openssl-*.tar.gz
+c) cd openssl-*/
+d) ./Configure $CONFIGURE_ARGS
+e) examine Makefile and compare with ../android-config.mk
+f) modify ../openssl.config as appropriate and go to step 3) above.
 
-
-c) Copy the new LICENSE file from OpenSSL distribution as NOTICE.
-   Create an empty MODULE_LICENSE_BSD_LIKE file.
-
-
-d) You may delete the following directories along with their contents,
-   since we won't use these (any more):
-
-     MacOS Netware VMS apps/demoCA apps/set bugs certs crypto/bf crypto/cast  \
-     crypto/cms crypto/idea crypto/md2 crypto/rc5 crypto/seed demos doc \
-     engines ms os2 perl shlib test times tools util
-
-   Also you may delete the following files:
-
-     CHANGES CHANGES.SSLeay ChangeLog.0_9_7-stable_not-in-head                \
-     ChangeLog.0_9_7-stable_not-in-head_FIPS Configure FAQ INSTALL            \
-     INSTALL.DJGPP INSTALL.MacOS INSTALL.NW INSTALL.OS2 INSTALL.VMS           \
-     INSTALL.W32 INSTALL.W64 INSTALL.WCE LICENSE Makefile Makefile.bak        \
-     Makefile.org Makefile.shared NEWS PROBLEMS README README.ASN1            \
-     README.ENGINE apps/CA.pl.bak config crypto/opensslconf.h.bak             \
-     install.com makevms.com openssl.doxy openssl.spec
-
-
-e) Go to include/openssl.  There's a bunch of symlinks here.  Since symlinks
-   can be a special case for version control, replace them by regular files:
-
-      for l in *.h; do cp $l copy_$l; rm $l; mv copy_$l $l; done
-
-   Some symlinks will remain, pointing to files that don't exit
-   (you deleted those in step d).  Delete the symlinks.
-
-
-f) Create Android.mk files based on those you find in the previous OpenSSL port:
-
-      Android.mk
-
-      apps/Android.mk
-      crypto/Android.mk
-      ssl/Android.mk
-
-   For the latter three, merge in any substantial changes between the
-   corresponding Makefiles in the OpenSSL distribution (apps/Makefile,
-   crypto/Makefile, crypto/*/Makefile, ssl/Makefile).
-   Don't forget to update the directory name for OpenSSL in these files
-   and whereever else it is used.
-
-
-g) Apply the patch found at the end of this file.
-
-
-h) Finally, create an updated version of this file (README.android)!
-
-
-
-
-Patch for apps directory:
-
---- openssl-0.9.8h-ORIG/apps/progs.h
-+++ openssl-0.9.8h/apps/progs.h
-@@ -22,7 +22,9 @@
- extern int x509_main(int argc,char *argv[]);
- extern int genrsa_main(int argc,char *argv[]);
- extern int gendsa_main(int argc,char *argv[]);
-+#if 0 /* ANDROID */
- extern int s_server_main(int argc,char *argv[]);
-+#endif
- extern int s_client_main(int argc,char *argv[]);
- extern int speed_main(int argc,char *argv[]);
- extern int s_time_main(int argc,char *argv[]);
-@@ -97,7 +99,9 @@
- 	{FUNC_TYPE_GENERAL,"gendsa",gendsa_main},
- #endif
- #if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
--	{FUNC_TYPE_GENERAL,"s_server",s_server_main},
-+#if 0 /* ANDROID */
-+        {FUNC_TYPE_GENERAL,"s_server",s_server_main},
-+#endif
- #endif
- #if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
- 	{FUNC_TYPE_GENERAL,"s_client",s_client_main},
-diff -ur openssl-0.9.8h-ORIG/apps/speed.c openssl-0.9.8h/apps/speed.c
---- openssl-0.9.8h-ORIG/apps/speed.c
-+++ openssl-0.9.8h/apps/speed.c
-@@ -108,12 +108,12 @@
- #include <signal.h>
- #endif
- 
--#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(OPENSSL_SYS_MACOSX)
-+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(OPENSSL_SYS_MACOSX) || defined(HAVE_ANDROID_OS)
- # define USE_TOD
- #elif !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VXWORKS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC))
- # define TIMES
- #endif
--#if !defined(_UNICOS) && !defined(__OpenBSD__) && !defined(sgi) && !defined(__FreeBSD__) && !(defined(__bsdi) || defined(__bsdi__)) && !defined(_AIX) && !defined(OPENSSL_SYS_MPE) && !defined(__NetBSD__) && !defined(OPENSSL_SYS_VXWORKS) /* FIXME */
-+#if !defined(_UNICOS) && !defined(__OpenBSD__) && !defined(sgi) && !defined(__FreeBSD__) && !(defined(__bsdi) || defined(__bsdi__)) && !defined(_AIX) && !defined(OPENSSL_SYS_MPE) && !defined(__NetBSD__) && !defined(OPENSSL_SYS_VXWORKS) && !defined(HAVE_ANDROID_OS) /* FIXME */
- # define TIMEB
- #endif
- 
-@@ -1836,6 +1836,7 @@
- 			}
- 		}
- 
-+#if 0 /* ANDROID */
- 	if (doit[D_IGE_128_AES])
- 		{
- 		for (j=0; j<SIZE_NUM; j++)
-@@ -1879,6 +1880,7 @@
- 			}
- 		}
- #endif
-+#endif
- #ifndef OPENSSL_NO_CAMELLIA
- 	if (doit[D_CBC_128_CML])
- 		{
diff --git a/android-config.mk b/android-config.mk
index 48007d9..970ceb8 100644
--- a/android-config.mk
+++ b/android-config.mk
@@ -7,4 +7,4 @@
 #
 
 LOCAL_CFLAGS += -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN -DOPENSSL_NO_HW
-LOCAL_CFLAGS += -DOPENSSL_NO_BF -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_CAST -DOPENSSL_NO_CMS -DOPENSSL_NO_GMP -DOPENSSL_NO_IDEA -DOPENSSL_NO_MDC2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SEED -DOPENSSL_NO_TLSEXT -DOPENSSL_NO_MD2 -DOPENSSL_NO_ENGINE -DOPENSSL_NO_EC -DOPENSSL_NO_ECDH -DOPENSSL_NO_ECDSA -DOPENSSL_NO_OCSP
+LOCAL_CFLAGS += -DOPENSSL_NO_BF -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_CAST -DOPENSSL_NO_CMS -DOPENSSL_NO_GMP -DOPENSSL_NO_IDEA -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MDC2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SEED -DOPENSSL_NO_TLSEXT -DOPENSSL_NO_MD2 -DOPENSSL_NO_ENGINE -DOPENSSL_NO_EC -DOPENSSL_NO_ECDH -DOPENSSL_NO_ECDSA -DOPENSSL_NO_OCSP
diff --git a/apps/Makefile b/apps/Makefile
index 92ae515..402981a 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -152,10 +152,13 @@
 	$(RM) $(EXE)
 	shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \
 		shlib_target="$(SHLIB_TARGET)"; \
+	elif [ -n "$(FIPSCANLIB)" ]; then \
+	  FIPSLD_CC=$(CC); CC=$(TOP)/fips/fipsld; export CC FIPSLD_CC; \
 	fi; \
 	LIBRARIES="$(LIBSSL) $(LIBKRB5) $(LIBCRYPTO)" ; \
+	[ "x$(FIPSCANLIB)" = "xlibfips" ] && LIBRARIES="$$LIBRARIES -lfips"; \
 	$(MAKE) -f $(TOP)/Makefile.shared -e \
-		APPNAME=$(EXE) OBJECTS="$(PROGRAM).o $(E_OBJ)" \
+		CC=$${CC} APPNAME=$(EXE) OBJECTS="$(PROGRAM).o $(E_OBJ)" \
 		LIBDEPS="$(PEX_LIBS) $$LIBRARIES $(EX_LIBS)" \
 		link_app.$${shlib_target}
 	-(cd ..; \
@@ -173,65 +176,66 @@
 app_rand.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
 app_rand.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 app_rand.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
-app_rand.o: ../include/openssl/evp.h ../include/openssl/lhash.h
-app_rand.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-app_rand.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
-app_rand.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-app_rand.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
-app_rand.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-app_rand.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-app_rand.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-app_rand.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h
-app_rand.o: app_rand.c apps.h
+app_rand.o: ../include/openssl/evp.h ../include/openssl/fips.h
+app_rand.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+app_rand.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+app_rand.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+app_rand.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+app_rand.o: ../include/openssl/rand.h ../include/openssl/safestack.h
+app_rand.o: ../include/openssl/sha.h ../include/openssl/stack.h
+app_rand.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+app_rand.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+app_rand.o: ../include/openssl/x509v3.h app_rand.c apps.h
 apps.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 apps.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 apps.o: ../include/openssl/conf.h ../include/openssl/crypto.h
 apps.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 apps.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 apps.o: ../include/openssl/engine.h ../include/openssl/err.h
-apps.o: ../include/openssl/evp.h ../include/openssl/lhash.h
-apps.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-apps.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
-apps.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-apps.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-apps.o: ../include/openssl/pkcs12.h ../include/openssl/pkcs7.h
-apps.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-apps.o: ../include/openssl/sha.h ../include/openssl/stack.h
-apps.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
-apps.o: ../include/openssl/ui.h ../include/openssl/x509.h
-apps.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.c apps.h
+apps.o: ../include/openssl/evp.h ../include/openssl/fips.h
+apps.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+apps.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+apps.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+apps.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+apps.o: ../include/openssl/pem2.h ../include/openssl/pkcs12.h
+apps.o: ../include/openssl/pkcs7.h ../include/openssl/rsa.h
+apps.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+apps.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+apps.o: ../include/openssl/txt_db.h ../include/openssl/ui.h
+apps.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+apps.o: ../include/openssl/x509v3.h apps.c apps.h
 asn1pars.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 asn1pars.o: ../include/openssl/buffer.h ../include/openssl/conf.h
 asn1pars.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
 asn1pars.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 asn1pars.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 asn1pars.o: ../include/openssl/err.h ../include/openssl/evp.h
-asn1pars.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-asn1pars.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-asn1pars.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-asn1pars.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-asn1pars.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-asn1pars.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-asn1pars.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-asn1pars.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-asn1pars.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
-asn1pars.o: asn1pars.c
+asn1pars.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+asn1pars.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+asn1pars.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+asn1pars.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+asn1pars.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+asn1pars.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+asn1pars.o: ../include/openssl/sha.h ../include/openssl/stack.h
+asn1pars.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+asn1pars.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+asn1pars.o: ../include/openssl/x509v3.h apps.h asn1pars.c
 ca.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 ca.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 ca.o: ../include/openssl/conf.h ../include/openssl/crypto.h
 ca.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 ca.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 ca.o: ../include/openssl/engine.h ../include/openssl/err.h
-ca.o: ../include/openssl/evp.h ../include/openssl/lhash.h
-ca.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-ca.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
-ca.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-ca.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-ca.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
-ca.o: ../include/openssl/sha.h ../include/openssl/stack.h
-ca.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
-ca.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-ca.o: ../include/openssl/x509v3.h apps.h ca.c
+ca.o: ../include/openssl/evp.h ../include/openssl/fips.h
+ca.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ca.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+ca.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ca.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ca.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+ca.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ca.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ca.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+ca.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h ca.c
 ciphers.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 ciphers.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 ciphers.o: ../include/openssl/comp.h ../include/openssl/conf.h
@@ -239,7 +243,8 @@
 ciphers.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 ciphers.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 ciphers.o: ../include/openssl/engine.h ../include/openssl/err.h
-ciphers.o: ../include/openssl/evp.h ../include/openssl/kssl.h
+ciphers.o: ../include/openssl/evp.h ../include/openssl/fips.h
+ciphers.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
 ciphers.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 ciphers.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
 ciphers.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -258,62 +263,63 @@
 cms.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
 cms.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 cms.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
-cms.o: ../include/openssl/evp.h ../include/openssl/lhash.h
-cms.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-cms.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
-cms.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-cms.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
-cms.o: ../include/openssl/sha.h ../include/openssl/stack.h
-cms.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
-cms.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-cms.o: ../include/openssl/x509v3.h apps.h cms.c
+cms.o: ../include/openssl/evp.h ../include/openssl/fips.h
+cms.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+cms.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+cms.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+cms.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+cms.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+cms.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+cms.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+cms.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h cms.c
 crl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 crl.o: ../include/openssl/buffer.h ../include/openssl/conf.h
 crl.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
 crl.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 crl.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 crl.o: ../include/openssl/err.h ../include/openssl/evp.h
-crl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-crl.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-crl.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-crl.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-crl.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-crl.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-crl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-crl.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-crl.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h crl.c
+crl.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+crl.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+crl.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+crl.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+crl.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+crl.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+crl.o: ../include/openssl/sha.h ../include/openssl/stack.h
+crl.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+crl.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+crl.o: ../include/openssl/x509v3.h apps.h crl.c
 crl2p7.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 crl2p7.o: ../include/openssl/buffer.h ../include/openssl/conf.h
 crl2p7.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
 crl2p7.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 crl2p7.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 crl2p7.o: ../include/openssl/err.h ../include/openssl/evp.h
-crl2p7.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-crl2p7.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-crl2p7.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-crl2p7.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-crl2p7.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-crl2p7.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-crl2p7.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-crl2p7.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-crl2p7.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
-crl2p7.o: crl2p7.c
+crl2p7.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+crl2p7.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+crl2p7.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+crl2p7.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+crl2p7.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+crl2p7.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+crl2p7.o: ../include/openssl/sha.h ../include/openssl/stack.h
+crl2p7.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+crl2p7.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+crl2p7.o: ../include/openssl/x509v3.h apps.h crl2p7.c
 dgst.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 dgst.o: ../include/openssl/buffer.h ../include/openssl/conf.h
 dgst.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
 dgst.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 dgst.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 dgst.o: ../include/openssl/err.h ../include/openssl/evp.h
-dgst.o: ../include/openssl/hmac.h ../include/openssl/lhash.h
-dgst.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-dgst.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
-dgst.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-dgst.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-dgst.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
-dgst.o: ../include/openssl/sha.h ../include/openssl/stack.h
-dgst.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
-dgst.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-dgst.o: ../include/openssl/x509v3.h apps.h dgst.c
+dgst.o: ../include/openssl/fips.h ../include/openssl/hmac.h
+dgst.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+dgst.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+dgst.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+dgst.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+dgst.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+dgst.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+dgst.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+dgst.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+dgst.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h dgst.c
 dh.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 dh.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 dh.o: ../include/openssl/conf.h ../include/openssl/crypto.h
@@ -321,15 +327,16 @@
 dh.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 dh.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 dh.o: ../include/openssl/err.h ../include/openssl/evp.h
-dh.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-dh.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-dh.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-dh.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-dh.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-dh.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-dh.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-dh.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-dh.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h dh.c
+dh.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+dh.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+dh.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+dh.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+dh.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+dh.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+dh.o: ../include/openssl/sha.h ../include/openssl/stack.h
+dh.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+dh.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+dh.o: ../include/openssl/x509v3.h apps.h dh.c
 dsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 dsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 dsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h
@@ -337,15 +344,16 @@
 dsa.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 dsa.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 dsa.o: ../include/openssl/err.h ../include/openssl/evp.h
-dsa.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-dsa.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-dsa.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-dsa.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-dsa.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-dsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-dsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-dsa.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-dsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h dsa.c
+dsa.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+dsa.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+dsa.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+dsa.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+dsa.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+dsa.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+dsa.o: ../include/openssl/sha.h ../include/openssl/stack.h
+dsa.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+dsa.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+dsa.o: ../include/openssl/x509v3.h apps.h dsa.c
 dsaparam.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 dsaparam.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 dsaparam.o: ../include/openssl/conf.h ../include/openssl/crypto.h
@@ -353,65 +361,68 @@
 dsaparam.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 dsaparam.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 dsaparam.o: ../include/openssl/engine.h ../include/openssl/err.h
-dsaparam.o: ../include/openssl/evp.h ../include/openssl/lhash.h
-dsaparam.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-dsaparam.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
-dsaparam.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-dsaparam.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-dsaparam.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
-dsaparam.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-dsaparam.o: ../include/openssl/sha.h ../include/openssl/stack.h
-dsaparam.o: ../include/openssl/store.h ../include/openssl/symhacks.h
-dsaparam.o: ../include/openssl/txt_db.h ../include/openssl/ui.h
-dsaparam.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-dsaparam.o: ../include/openssl/x509v3.h apps.h dsaparam.c
+dsaparam.o: ../include/openssl/evp.h ../include/openssl/fips.h
+dsaparam.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+dsaparam.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+dsaparam.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+dsaparam.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+dsaparam.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+dsaparam.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+dsaparam.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+dsaparam.o: ../include/openssl/stack.h ../include/openssl/store.h
+dsaparam.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+dsaparam.o: ../include/openssl/ui.h ../include/openssl/x509.h
+dsaparam.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+dsaparam.o: dsaparam.c
 ec.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 ec.o: ../include/openssl/buffer.h ../include/openssl/conf.h
 ec.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
 ec.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 ec.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 ec.o: ../include/openssl/err.h ../include/openssl/evp.h
-ec.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-ec.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-ec.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-ec.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-ec.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-ec.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-ec.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-ec.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-ec.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h ec.c
+ec.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+ec.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+ec.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+ec.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ec.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+ec.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+ec.o: ../include/openssl/sha.h ../include/openssl/stack.h
+ec.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+ec.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+ec.o: ../include/openssl/x509v3.h apps.h ec.c
 ecparam.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 ecparam.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 ecparam.o: ../include/openssl/conf.h ../include/openssl/crypto.h
 ecparam.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 ecparam.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 ecparam.o: ../include/openssl/engine.h ../include/openssl/err.h
-ecparam.o: ../include/openssl/evp.h ../include/openssl/lhash.h
-ecparam.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-ecparam.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
-ecparam.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-ecparam.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-ecparam.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
-ecparam.o: ../include/openssl/sha.h ../include/openssl/stack.h
-ecparam.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
-ecparam.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-ecparam.o: ../include/openssl/x509v3.h apps.h ecparam.c
+ecparam.o: ../include/openssl/evp.h ../include/openssl/fips.h
+ecparam.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ecparam.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+ecparam.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ecparam.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ecparam.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+ecparam.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ecparam.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ecparam.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+ecparam.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+ecparam.o: ecparam.c
 enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 enc.o: ../include/openssl/buffer.h ../include/openssl/conf.h
 enc.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
 enc.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 enc.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 enc.o: ../include/openssl/err.h ../include/openssl/evp.h
-enc.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-enc.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-enc.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-enc.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-enc.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-enc.o: ../include/openssl/rand.h ../include/openssl/safestack.h
-enc.o: ../include/openssl/sha.h ../include/openssl/stack.h
-enc.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
-enc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-enc.o: ../include/openssl/x509v3.h apps.h enc.c
+enc.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+enc.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+enc.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+enc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+enc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+enc.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+enc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+enc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+enc.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+enc.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h enc.c
 engine.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 engine.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 engine.o: ../include/openssl/comp.h ../include/openssl/conf.h
@@ -419,7 +430,8 @@
 engine.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 engine.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 engine.o: ../include/openssl/engine.h ../include/openssl/err.h
-engine.o: ../include/openssl/evp.h ../include/openssl/kssl.h
+engine.o: ../include/openssl/evp.h ../include/openssl/fips.h
+engine.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
 engine.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 engine.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
 engine.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -440,7 +452,8 @@
 errstr.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 errstr.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 errstr.o: ../include/openssl/engine.h ../include/openssl/err.h
-errstr.o: ../include/openssl/evp.h ../include/openssl/kssl.h
+errstr.o: ../include/openssl/evp.h ../include/openssl/fips.h
+errstr.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
 errstr.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 errstr.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
 errstr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -461,18 +474,19 @@
 gendh.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 gendh.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 gendh.o: ../include/openssl/engine.h ../include/openssl/err.h
-gendh.o: ../include/openssl/evp.h ../include/openssl/lhash.h
-gendh.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-gendh.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
-gendh.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-gendh.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-gendh.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
-gendh.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-gendh.o: ../include/openssl/sha.h ../include/openssl/stack.h
-gendh.o: ../include/openssl/store.h ../include/openssl/symhacks.h
-gendh.o: ../include/openssl/txt_db.h ../include/openssl/ui.h
-gendh.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-gendh.o: ../include/openssl/x509v3.h apps.h gendh.c
+gendh.o: ../include/openssl/evp.h ../include/openssl/fips.h
+gendh.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+gendh.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+gendh.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+gendh.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+gendh.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+gendh.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+gendh.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+gendh.o: ../include/openssl/stack.h ../include/openssl/store.h
+gendh.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+gendh.o: ../include/openssl/ui.h ../include/openssl/x509.h
+gendh.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+gendh.o: gendh.c
 gendsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 gendsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 gendsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h
@@ -480,16 +494,16 @@
 gendsa.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 gendsa.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 gendsa.o: ../include/openssl/err.h ../include/openssl/evp.h
-gendsa.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-gendsa.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-gendsa.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-gendsa.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-gendsa.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-gendsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-gendsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-gendsa.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-gendsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
-gendsa.o: gendsa.c
+gendsa.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+gendsa.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+gendsa.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+gendsa.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+gendsa.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+gendsa.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+gendsa.o: ../include/openssl/sha.h ../include/openssl/stack.h
+gendsa.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+gendsa.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+gendsa.o: ../include/openssl/x509v3.h apps.h gendsa.c
 genrsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 genrsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 genrsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h
@@ -497,33 +511,35 @@
 genrsa.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 genrsa.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 genrsa.o: ../include/openssl/engine.h ../include/openssl/err.h
-genrsa.o: ../include/openssl/evp.h ../include/openssl/lhash.h
-genrsa.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-genrsa.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
-genrsa.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-genrsa.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-genrsa.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
-genrsa.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-genrsa.o: ../include/openssl/sha.h ../include/openssl/stack.h
-genrsa.o: ../include/openssl/store.h ../include/openssl/symhacks.h
-genrsa.o: ../include/openssl/txt_db.h ../include/openssl/ui.h
-genrsa.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-genrsa.o: ../include/openssl/x509v3.h apps.h genrsa.c
+genrsa.o: ../include/openssl/evp.h ../include/openssl/fips.h
+genrsa.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+genrsa.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+genrsa.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+genrsa.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+genrsa.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+genrsa.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+genrsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+genrsa.o: ../include/openssl/stack.h ../include/openssl/store.h
+genrsa.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+genrsa.o: ../include/openssl/ui.h ../include/openssl/x509.h
+genrsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+genrsa.o: genrsa.c
 nseq.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 nseq.o: ../include/openssl/buffer.h ../include/openssl/conf.h
 nseq.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
 nseq.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 nseq.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 nseq.o: ../include/openssl/err.h ../include/openssl/evp.h
-nseq.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-nseq.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-nseq.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-nseq.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-nseq.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-nseq.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-nseq.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-nseq.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-nseq.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h nseq.c
+nseq.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+nseq.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+nseq.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+nseq.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+nseq.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+nseq.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+nseq.o: ../include/openssl/sha.h ../include/openssl/stack.h
+nseq.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+nseq.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+nseq.o: ../include/openssl/x509v3.h apps.h nseq.c
 ocsp.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 ocsp.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 ocsp.o: ../include/openssl/comp.h ../include/openssl/conf.h
@@ -531,7 +547,8 @@
 ocsp.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 ocsp.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 ocsp.o: ../include/openssl/engine.h ../include/openssl/err.h
-ocsp.o: ../include/openssl/evp.h ../include/openssl/kssl.h
+ocsp.o: ../include/openssl/evp.h ../include/openssl/fips.h
+ocsp.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
 ocsp.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 ocsp.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
 ocsp.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -552,7 +569,8 @@
 openssl.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 openssl.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 openssl.o: ../include/openssl/engine.h ../include/openssl/err.h
-openssl.o: ../include/openssl/evp.h ../include/openssl/kssl.h
+openssl.o: ../include/openssl/evp.h ../include/openssl/fips.h
+openssl.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
 openssl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 openssl.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
 openssl.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -573,95 +591,97 @@
 passwd.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 passwd.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 passwd.o: ../include/openssl/err.h ../include/openssl/evp.h
-passwd.o: ../include/openssl/lhash.h ../include/openssl/md5.h
-passwd.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-passwd.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
-passwd.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-passwd.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
-passwd.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-passwd.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-passwd.o: ../include/openssl/txt_db.h ../include/openssl/ui.h
-passwd.o: ../include/openssl/ui_compat.h ../include/openssl/x509.h
-passwd.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
-passwd.o: passwd.c
+passwd.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+passwd.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
+passwd.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+passwd.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+passwd.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+passwd.o: ../include/openssl/rand.h ../include/openssl/safestack.h
+passwd.o: ../include/openssl/sha.h ../include/openssl/stack.h
+passwd.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+passwd.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h
+passwd.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+passwd.o: ../include/openssl/x509v3.h apps.h passwd.c
 pkcs12.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 pkcs12.o: ../include/openssl/buffer.h ../include/openssl/conf.h
 pkcs12.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
 pkcs12.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 pkcs12.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 pkcs12.o: ../include/openssl/err.h ../include/openssl/evp.h
-pkcs12.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-pkcs12.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-pkcs12.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-pkcs12.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-pkcs12.o: ../include/openssl/pem2.h ../include/openssl/pkcs12.h
-pkcs12.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
-pkcs12.o: ../include/openssl/sha.h ../include/openssl/stack.h
-pkcs12.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
-pkcs12.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-pkcs12.o: ../include/openssl/x509v3.h apps.h pkcs12.c
+pkcs12.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+pkcs12.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+pkcs12.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+pkcs12.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+pkcs12.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+pkcs12.o: ../include/openssl/pkcs12.h ../include/openssl/pkcs7.h
+pkcs12.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+pkcs12.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+pkcs12.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+pkcs12.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+pkcs12.o: pkcs12.c
 pkcs7.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 pkcs7.o: ../include/openssl/buffer.h ../include/openssl/conf.h
 pkcs7.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
 pkcs7.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 pkcs7.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 pkcs7.o: ../include/openssl/err.h ../include/openssl/evp.h
-pkcs7.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-pkcs7.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-pkcs7.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-pkcs7.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-pkcs7.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-pkcs7.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-pkcs7.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-pkcs7.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-pkcs7.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
-pkcs7.o: pkcs7.c
+pkcs7.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+pkcs7.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+pkcs7.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+pkcs7.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+pkcs7.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+pkcs7.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+pkcs7.o: ../include/openssl/sha.h ../include/openssl/stack.h
+pkcs7.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+pkcs7.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+pkcs7.o: ../include/openssl/x509v3.h apps.h pkcs7.c
 pkcs8.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 pkcs8.o: ../include/openssl/buffer.h ../include/openssl/conf.h
 pkcs8.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
 pkcs8.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 pkcs8.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 pkcs8.o: ../include/openssl/err.h ../include/openssl/evp.h
-pkcs8.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-pkcs8.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-pkcs8.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-pkcs8.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-pkcs8.o: ../include/openssl/pem2.h ../include/openssl/pkcs12.h
-pkcs8.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
-pkcs8.o: ../include/openssl/sha.h ../include/openssl/stack.h
-pkcs8.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
-pkcs8.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-pkcs8.o: ../include/openssl/x509v3.h apps.h pkcs8.c
+pkcs8.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+pkcs8.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+pkcs8.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+pkcs8.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+pkcs8.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+pkcs8.o: ../include/openssl/pkcs12.h ../include/openssl/pkcs7.h
+pkcs8.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+pkcs8.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+pkcs8.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+pkcs8.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+pkcs8.o: pkcs8.c
 prime.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 prime.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 prime.o: ../include/openssl/conf.h ../include/openssl/crypto.h
 prime.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 prime.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 prime.o: ../include/openssl/engine.h ../include/openssl/evp.h
-prime.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-prime.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-prime.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-prime.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
-prime.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-prime.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-prime.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-prime.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
-prime.o: prime.c
+prime.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+prime.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+prime.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+prime.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+prime.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+prime.o: ../include/openssl/sha.h ../include/openssl/stack.h
+prime.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+prime.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+prime.o: ../include/openssl/x509v3.h apps.h prime.c
 rand.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 rand.o: ../include/openssl/buffer.h ../include/openssl/conf.h
 rand.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
 rand.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 rand.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 rand.o: ../include/openssl/err.h ../include/openssl/evp.h
-rand.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-rand.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-rand.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-rand.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
-rand.o: ../include/openssl/rand.h ../include/openssl/safestack.h
-rand.o: ../include/openssl/sha.h ../include/openssl/stack.h
-rand.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
-rand.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-rand.o: ../include/openssl/x509v3.h apps.h rand.c
+rand.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+rand.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+rand.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+rand.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+rand.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+rand.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+rand.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+rand.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+rand.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h rand.c
 req.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 req.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 req.o: ../include/openssl/conf.h ../include/openssl/crypto.h
@@ -669,50 +689,52 @@
 req.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 req.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 req.o: ../include/openssl/engine.h ../include/openssl/err.h
-req.o: ../include/openssl/evp.h ../include/openssl/lhash.h
-req.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-req.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
-req.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-req.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-req.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
-req.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-req.o: ../include/openssl/sha.h ../include/openssl/stack.h
-req.o: ../include/openssl/store.h ../include/openssl/symhacks.h
-req.o: ../include/openssl/txt_db.h ../include/openssl/ui.h
-req.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-req.o: ../include/openssl/x509v3.h apps.h req.c
+req.o: ../include/openssl/evp.h ../include/openssl/fips.h
+req.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+req.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+req.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+req.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+req.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+req.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+req.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+req.o: ../include/openssl/stack.h ../include/openssl/store.h
+req.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+req.o: ../include/openssl/ui.h ../include/openssl/x509.h
+req.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h req.c
 rsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 rsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 rsa.o: ../include/openssl/conf.h ../include/openssl/crypto.h
 rsa.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 rsa.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 rsa.o: ../include/openssl/engine.h ../include/openssl/err.h
-rsa.o: ../include/openssl/evp.h ../include/openssl/lhash.h
-rsa.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-rsa.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
-rsa.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-rsa.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-rsa.o: ../include/openssl/pkcs7.h ../include/openssl/rsa.h
-rsa.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-rsa.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-rsa.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-rsa.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h rsa.c
+rsa.o: ../include/openssl/evp.h ../include/openssl/fips.h
+rsa.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+rsa.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+rsa.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+rsa.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+rsa.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+rsa.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+rsa.o: ../include/openssl/sha.h ../include/openssl/stack.h
+rsa.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+rsa.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+rsa.o: ../include/openssl/x509v3.h apps.h rsa.c
 rsautl.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 rsautl.o: ../include/openssl/buffer.h ../include/openssl/conf.h
 rsautl.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
 rsautl.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 rsautl.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 rsautl.o: ../include/openssl/err.h ../include/openssl/evp.h
-rsautl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-rsautl.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-rsautl.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-rsautl.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-rsautl.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-rsautl.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-rsautl.o: ../include/openssl/sha.h ../include/openssl/stack.h
-rsautl.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
-rsautl.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-rsautl.o: ../include/openssl/x509v3.h apps.h rsautl.c
+rsautl.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+rsautl.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+rsautl.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+rsautl.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+rsautl.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+rsautl.o: ../include/openssl/pkcs7.h ../include/openssl/rsa.h
+rsautl.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+rsautl.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+rsautl.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+rsautl.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+rsautl.o: rsautl.c
 s_cb.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 s_cb.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 s_cb.o: ../include/openssl/comp.h ../include/openssl/conf.h
@@ -720,7 +742,8 @@
 s_cb.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s_cb.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s_cb.o: ../include/openssl/engine.h ../include/openssl/err.h
-s_cb.o: ../include/openssl/evp.h ../include/openssl/kssl.h
+s_cb.o: ../include/openssl/evp.h ../include/openssl/fips.h
+s_cb.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
 s_cb.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 s_cb.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
 s_cb.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -741,7 +764,8 @@
 s_client.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s_client.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s_client.o: ../include/openssl/engine.h ../include/openssl/err.h
-s_client.o: ../include/openssl/evp.h ../include/openssl/kssl.h
+s_client.o: ../include/openssl/evp.h ../include/openssl/fips.h
+s_client.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
 s_client.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 s_client.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
 s_client.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -764,7 +788,8 @@
 s_server.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s_server.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s_server.o: ../include/openssl/engine.h ../include/openssl/err.h
-s_server.o: ../include/openssl/evp.h ../include/openssl/kssl.h
+s_server.o: ../include/openssl/evp.h ../include/openssl/fips.h
+s_server.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
 s_server.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 s_server.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
 s_server.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -787,6 +812,7 @@
 s_socket.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s_socket.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s_socket.o: ../include/openssl/engine.h ../include/openssl/evp.h
+s_socket.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 s_socket.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 s_socket.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 s_socket.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
@@ -808,7 +834,8 @@
 s_time.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s_time.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s_time.o: ../include/openssl/engine.h ../include/openssl/err.h
-s_time.o: ../include/openssl/evp.h ../include/openssl/kssl.h
+s_time.o: ../include/openssl/evp.h ../include/openssl/fips.h
+s_time.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
 s_time.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 s_time.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
 s_time.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -829,7 +856,8 @@
 sess_id.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 sess_id.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 sess_id.o: ../include/openssl/engine.h ../include/openssl/err.h
-sess_id.o: ../include/openssl/evp.h ../include/openssl/kssl.h
+sess_id.o: ../include/openssl/evp.h ../include/openssl/fips.h
+sess_id.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
 sess_id.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 sess_id.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
 sess_id.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -849,16 +877,16 @@
 smime.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 smime.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 smime.o: ../include/openssl/err.h ../include/openssl/evp.h
-smime.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-smime.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-smime.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-smime.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-smime.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-smime.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-smime.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-smime.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-smime.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
-smime.o: smime.c
+smime.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+smime.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+smime.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+smime.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+smime.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+smime.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+smime.o: ../include/openssl/sha.h ../include/openssl/stack.h
+smime.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+smime.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+smime.o: ../include/openssl/x509v3.h apps.h smime.c
 speed.o: ../e_os.h ../include/openssl/aes.h ../include/openssl/asn1.h
 speed.o: ../include/openssl/bio.h ../include/openssl/blowfish.h
 speed.o: ../include/openssl/bn.h ../include/openssl/buffer.h
@@ -868,53 +896,54 @@
 speed.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 speed.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 speed.o: ../include/openssl/engine.h ../include/openssl/err.h
-speed.o: ../include/openssl/evp.h ../include/openssl/hmac.h
-speed.o: ../include/openssl/idea.h ../include/openssl/lhash.h
-speed.o: ../include/openssl/md2.h ../include/openssl/md4.h
-speed.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
-speed.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-speed.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-speed.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
-speed.o: ../include/openssl/rand.h ../include/openssl/rc2.h
-speed.o: ../include/openssl/rc4.h ../include/openssl/ripemd.h
-speed.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-speed.o: ../include/openssl/sha.h ../include/openssl/stack.h
-speed.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
-speed.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h
-speed.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-speed.o: ../include/openssl/x509v3.h apps.h speed.c testdsa.h testrsa.h
+speed.o: ../include/openssl/evp.h ../include/openssl/fips.h
+speed.o: ../include/openssl/hmac.h ../include/openssl/idea.h
+speed.o: ../include/openssl/lhash.h ../include/openssl/md2.h
+speed.o: ../include/openssl/md4.h ../include/openssl/md5.h
+speed.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+speed.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+speed.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+speed.o: ../include/openssl/pkcs7.h ../include/openssl/rand.h
+speed.o: ../include/openssl/rc2.h ../include/openssl/rc4.h
+speed.o: ../include/openssl/ripemd.h ../include/openssl/rsa.h
+speed.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+speed.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+speed.o: ../include/openssl/txt_db.h ../include/openssl/ui.h
+speed.o: ../include/openssl/ui_compat.h ../include/openssl/x509.h
+speed.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
+speed.o: speed.c testdsa.h testrsa.h
 spkac.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 spkac.o: ../include/openssl/buffer.h ../include/openssl/conf.h
 spkac.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
 spkac.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 spkac.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 spkac.o: ../include/openssl/err.h ../include/openssl/evp.h
-spkac.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-spkac.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-spkac.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-spkac.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-spkac.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-spkac.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-spkac.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-spkac.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-spkac.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
-spkac.o: spkac.c
+spkac.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+spkac.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+spkac.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+spkac.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+spkac.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+spkac.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+spkac.o: ../include/openssl/sha.h ../include/openssl/stack.h
+spkac.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+spkac.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+spkac.o: ../include/openssl/x509v3.h apps.h spkac.c
 verify.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 verify.o: ../include/openssl/buffer.h ../include/openssl/conf.h
 verify.o: ../include/openssl/crypto.h ../include/openssl/e_os2.h
 verify.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 verify.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 verify.o: ../include/openssl/err.h ../include/openssl/evp.h
-verify.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-verify.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-verify.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-verify.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-verify.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-verify.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-verify.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-verify.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
-verify.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
-verify.o: verify.c
+verify.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+verify.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+verify.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+verify.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+verify.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+verify.o: ../include/openssl/pkcs7.h ../include/openssl/safestack.h
+verify.o: ../include/openssl/sha.h ../include/openssl/stack.h
+verify.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+verify.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+verify.o: ../include/openssl/x509v3.h apps.h verify.c
 version.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 version.o: ../include/openssl/blowfish.h ../include/openssl/bn.h
 version.o: ../include/openssl/buffer.h ../include/openssl/conf.h
@@ -922,18 +951,18 @@
 version.o: ../include/openssl/des_old.h ../include/openssl/e_os2.h
 version.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 version.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
-version.o: ../include/openssl/evp.h ../include/openssl/idea.h
-version.o: ../include/openssl/lhash.h ../include/openssl/md2.h
-version.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-version.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
-version.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-version.o: ../include/openssl/pkcs7.h ../include/openssl/rc4.h
-version.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-version.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-version.o: ../include/openssl/txt_db.h ../include/openssl/ui.h
-version.o: ../include/openssl/ui_compat.h ../include/openssl/x509.h
-version.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h
-version.o: version.c
+version.o: ../include/openssl/evp.h ../include/openssl/fips.h
+version.o: ../include/openssl/idea.h ../include/openssl/lhash.h
+version.o: ../include/openssl/md2.h ../include/openssl/obj_mac.h
+version.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+version.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+version.o: ../include/openssl/ossl_typ.h ../include/openssl/pkcs7.h
+version.o: ../include/openssl/rc4.h ../include/openssl/safestack.h
+version.o: ../include/openssl/sha.h ../include/openssl/stack.h
+version.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
+version.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h
+version.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+version.o: ../include/openssl/x509v3.h apps.h version.c
 x509.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 x509.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 x509.o: ../include/openssl/conf.h ../include/openssl/crypto.h
@@ -941,13 +970,13 @@
 x509.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 x509.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
 x509.o: ../include/openssl/err.h ../include/openssl/evp.h
-x509.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
-x509.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
-x509.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-x509.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-x509.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-x509.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-x509.o: ../include/openssl/sha.h ../include/openssl/stack.h
-x509.o: ../include/openssl/symhacks.h ../include/openssl/txt_db.h
-x509.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-x509.o: ../include/openssl/x509v3.h apps.h x509.c
+x509.o: ../include/openssl/fips.h ../include/openssl/lhash.h
+x509.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
+x509.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
+x509.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+x509.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+x509.o: ../include/openssl/pkcs7.h ../include/openssl/rsa.h
+x509.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+x509.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+x509.o: ../include/openssl/txt_db.h ../include/openssl/x509.h
+x509.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h apps.h x509.c
diff --git a/apps/apps.c b/apps/apps.c
index 5209cab..498722a 100644
--- a/apps/apps.c
+++ b/apps/apps.c
@@ -115,6 +115,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <ctype.h>
+#include <assert.h>
 #include <openssl/err.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
@@ -129,6 +130,9 @@
 #include <openssl/rsa.h>
 #endif
 #include <openssl/bn.h>
+#ifndef OPENSSL_NO_JPAKE
+#include <openssl/jpake.h>
+#endif
 
 #define NON_MAIN
 #include "apps.h"
@@ -2333,3 +2337,233 @@
 	if (free_out)
 		BIO_free(out);
 	}
+
+#ifndef OPENSSL_NO_JPAKE
+
+static JPAKE_CTX *jpake_init(const char *us, const char *them,
+							 const char *secret)
+	{
+	BIGNUM *p = NULL;
+	BIGNUM *g = NULL;
+	BIGNUM *q = NULL;
+	BIGNUM *bnsecret = BN_new();
+	JPAKE_CTX *ctx;
+
+	/* Use a safe prime for p (that we found earlier) */
+	BN_hex2bn(&p, "F9E5B365665EA7A05A9C534502780FEE6F1AB5BD4F49947FD036DBD7E905269AF46EF28B0FC07487EE4F5D20FB3C0AF8E700F3A2FA3414970CBED44FEDFF80CE78D800F184BB82435D137AADA2C6C16523247930A63B85661D1FC817A51ACD96168E95898A1F83A79FFB529368AA7833ABD1B0C3AEDDB14D2E1A2F71D99F763F");
+	g = BN_new();
+	BN_set_word(g, 2);
+	q = BN_new();
+	BN_rshift1(q, p);
+
+	BN_bin2bn((const unsigned char *)secret, strlen(secret), bnsecret);
+
+	ctx = JPAKE_CTX_new(us, them, p, g, q, bnsecret);
+	BN_free(bnsecret);
+	BN_free(q);
+	BN_free(g);
+	BN_free(p);
+
+	return ctx;
+	}
+
+static void jpake_send_part(BIO *conn, const JPAKE_STEP_PART *p)
+	{
+	BN_print(conn, p->gx);
+	BIO_puts(conn, "\n");
+	BN_print(conn, p->zkpx.gr);
+	BIO_puts(conn, "\n");
+	BN_print(conn, p->zkpx.b);
+	BIO_puts(conn, "\n");
+	}
+
+static void jpake_send_step1(BIO *bconn, JPAKE_CTX *ctx)
+	{
+	JPAKE_STEP1 s1;
+
+	JPAKE_STEP1_init(&s1);
+	JPAKE_STEP1_generate(&s1, ctx);
+	jpake_send_part(bconn, &s1.p1);
+	jpake_send_part(bconn, &s1.p2);
+	(void)BIO_flush(bconn);
+	JPAKE_STEP1_release(&s1);
+	}
+
+static void jpake_send_step2(BIO *bconn, JPAKE_CTX *ctx)
+	{
+	JPAKE_STEP2 s2;
+
+	JPAKE_STEP2_init(&s2);
+	JPAKE_STEP2_generate(&s2, ctx);
+	jpake_send_part(bconn, &s2);
+	(void)BIO_flush(bconn);
+	JPAKE_STEP2_release(&s2);
+	}
+
+static void jpake_send_step3a(BIO *bconn, JPAKE_CTX *ctx)
+	{
+	JPAKE_STEP3A s3a;
+
+	JPAKE_STEP3A_init(&s3a);
+	JPAKE_STEP3A_generate(&s3a, ctx);
+	BIO_write(bconn, s3a.hhk, sizeof s3a.hhk);
+	(void)BIO_flush(bconn);
+	JPAKE_STEP3A_release(&s3a);
+	}
+
+static void jpake_send_step3b(BIO *bconn, JPAKE_CTX *ctx)
+	{
+	JPAKE_STEP3B s3b;
+
+	JPAKE_STEP3B_init(&s3b);
+	JPAKE_STEP3B_generate(&s3b, ctx);
+	BIO_write(bconn, s3b.hk, sizeof s3b.hk);
+	(void)BIO_flush(bconn);
+	JPAKE_STEP3B_release(&s3b);
+	}
+
+static void readbn(BIGNUM **bn, BIO *bconn)
+	{
+	char buf[10240];
+	int l;
+
+	l = BIO_gets(bconn, buf, sizeof buf);
+	assert(l > 0);
+	assert(buf[l-1] == '\n');
+	buf[l-1] = '\0';
+	BN_hex2bn(bn, buf);
+	}
+
+static void jpake_receive_part(JPAKE_STEP_PART *p, BIO *bconn)
+	{
+	readbn(&p->gx, bconn);
+	readbn(&p->zkpx.gr, bconn);
+	readbn(&p->zkpx.b, bconn);
+	}
+
+static void jpake_receive_step1(JPAKE_CTX *ctx, BIO *bconn)
+	{
+	JPAKE_STEP1 s1;
+
+	JPAKE_STEP1_init(&s1);
+	jpake_receive_part(&s1.p1, bconn);
+	jpake_receive_part(&s1.p2, bconn);
+	if(!JPAKE_STEP1_process(ctx, &s1))
+		{
+		ERR_print_errors(bio_err);
+		exit(1);
+		}
+	JPAKE_STEP1_release(&s1);
+	}
+
+static void jpake_receive_step2(JPAKE_CTX *ctx, BIO *bconn)
+	{
+	JPAKE_STEP2 s2;
+
+	JPAKE_STEP2_init(&s2);
+	jpake_receive_part(&s2, bconn);
+	if(!JPAKE_STEP2_process(ctx, &s2))
+		{
+		ERR_print_errors(bio_err);
+		exit(1);
+		}
+	JPAKE_STEP2_release(&s2);
+	}
+
+static void jpake_receive_step3a(JPAKE_CTX *ctx, BIO *bconn)
+	{
+	JPAKE_STEP3A s3a;
+	int l;
+
+	JPAKE_STEP3A_init(&s3a);
+	l = BIO_read(bconn, s3a.hhk, sizeof s3a.hhk);
+	assert(l == sizeof s3a.hhk);
+	if(!JPAKE_STEP3A_process(ctx, &s3a))
+		{
+		ERR_print_errors(bio_err);
+		exit(1);
+		}
+	JPAKE_STEP3A_release(&s3a);
+	}
+
+static void jpake_receive_step3b(JPAKE_CTX *ctx, BIO *bconn)
+	{
+	JPAKE_STEP3B s3b;
+	int l;
+
+	JPAKE_STEP3B_init(&s3b);
+	l = BIO_read(bconn, s3b.hk, sizeof s3b.hk);
+	assert(l == sizeof s3b.hk);
+	if(!JPAKE_STEP3B_process(ctx, &s3b))
+		{
+		ERR_print_errors(bio_err);
+		exit(1);
+		}
+	JPAKE_STEP3B_release(&s3b);
+	}
+
+void jpake_client_auth(BIO *out, BIO *conn, const char *secret)
+	{
+	JPAKE_CTX *ctx;
+	BIO *bconn;
+
+	BIO_puts(out, "Authenticating with JPAKE\n");
+
+	ctx = jpake_init("client", "server", secret);
+
+	bconn = BIO_new(BIO_f_buffer());
+	BIO_push(bconn, conn);
+
+	jpake_send_step1(bconn, ctx);
+	jpake_receive_step1(ctx, bconn);
+	jpake_send_step2(bconn, ctx);
+	jpake_receive_step2(ctx, bconn);
+	jpake_send_step3a(bconn, ctx);
+	jpake_receive_step3b(ctx, bconn);
+
+	/*
+	 * The problem is that you must use the derived key in the
+	 * session key or you are subject to man-in-the-middle
+	 * attacks.
+	 */
+	BIO_puts(out, "JPAKE authentication succeeded (N.B. This version can"
+		 " be MitMed. See the version in HEAD for how to do it"
+		 " properly)\n");
+
+	BIO_pop(bconn);
+	BIO_free(bconn);
+	}
+
+void jpake_server_auth(BIO *out, BIO *conn, const char *secret)
+	{
+	JPAKE_CTX *ctx;
+	BIO *bconn;
+
+	BIO_puts(out, "Authenticating with JPAKE\n");
+
+	ctx = jpake_init("server", "client", secret);
+
+	bconn = BIO_new(BIO_f_buffer());
+	BIO_push(bconn, conn);
+
+	jpake_receive_step1(ctx, bconn);
+	jpake_send_step1(bconn, ctx);
+	jpake_receive_step2(ctx, bconn);
+	jpake_send_step2(bconn, ctx);
+	jpake_receive_step3a(ctx, bconn);
+	jpake_send_step3b(bconn, ctx);
+
+	/*
+	 * The problem is that you must use the derived key in the
+	 * session key or you are subject to man-in-the-middle
+	 * attacks.
+	 */
+	BIO_puts(out, "JPAKE authentication succeeded (N.B. This version can"
+		 " be MitMed. See the version in HEAD for how to do it"
+		 " properly)\n");
+
+	BIO_pop(bconn);
+	BIO_free(bconn);
+	}
+
+#endif
diff --git a/apps/apps.h b/apps/apps.h
index 0df1708..8857909 100644
--- a/apps/apps.h
+++ b/apps/apps.h
@@ -149,9 +149,11 @@
 #ifndef NON_MAIN
 CONF *config=NULL;
 BIO *bio_err=NULL;
+int in_FIPS_mode=0;
 #else
 extern CONF *config;
 extern BIO *bio_err;
+extern int in_FIPS_mode;
 #endif
 
 #else
@@ -160,6 +162,7 @@
 extern CONF *config;
 extern char *default_config_file;
 extern BIO *bio_err;
+extern int in_FIPS_mode;
 
 #endif
 
@@ -335,6 +338,10 @@
 int args_verify(char ***pargs, int *pargc,
 			int *badarg, BIO *err, X509_VERIFY_PARAM **pm);
 void policies_print(BIO *out, X509_STORE_CTX *ctx);
+#ifndef OPENSSL_NO_JPAKE
+void jpake_client_auth(BIO *out, BIO *conn, const char *secret);
+void jpake_server_auth(BIO *out, BIO *conn, const char *secret);
+#endif
 
 #define FORMAT_UNDEF    0
 #define FORMAT_ASN1     1
diff --git a/apps/asn1pars.c b/apps/asn1pars.c
index b1a7c8e..bde61d0 100644
--- a/apps/asn1pars.c
+++ b/apps/asn1pars.c
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 
-/* A nice addition from Dr Stephen Henson <[email protected]> to 
+/* A nice addition from Dr Stephen Henson <[email protected]> to 
  * add the -strparse option which parses nested binary structures
  */
 
diff --git a/apps/ca.c b/apps/ca.c
index 87f0405..68516ee 100644
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -83,7 +83,7 @@
 #    else
 #      include <unixlib.h>
 #    endif
-#  elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_NETWARE)
+#  elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_NETWARE) && !defined(__TANDEM)
 #    include <sys/file.h>
 #  endif
 #endif
diff --git a/apps/crl.c b/apps/crl.c
index a0040fb..c395b2a 100644
--- a/apps/crl.c
+++ b/apps/crl.c
@@ -85,6 +85,7 @@
 " -issuer         - print issuer DN\n",
 " -lastupdate     - lastUpdate field\n",
 " -nextupdate     - nextUpdate field\n",
+" -crlnumber      - print CRL number\n",
 " -noout          - no CRL output\n",
 " -CAfile  name   - verify CRL using certificates in file \"name\"\n",
 " -CApath  dir    - verify CRL using certificates in \"dir\"\n",
@@ -107,7 +108,7 @@
 	int informat,outformat;
 	char *infile=NULL,*outfile=NULL;
 	int hash=0,issuer=0,lastupdate=0,nextupdate=0,noout=0,text=0;
-	int fingerprint = 0;
+	int fingerprint = 0, crlnumber = 0;
 	const char **pp;
 	X509_STORE *store = NULL;
 	X509_STORE_CTX ctx;
@@ -206,6 +207,8 @@
 			noout= ++num;
 		else if (strcmp(*argv,"-fingerprint") == 0)
 			fingerprint= ++num;
+		else if (strcmp(*argv,"-crlnumber") == 0)
+			crlnumber= ++num;
 		else if ((md_alg=EVP_get_digestbyname(*argv + 1)))
 			{
 			/* ok */
@@ -281,7 +284,21 @@
 				{
 				print_name(bio_out, "issuer=", X509_CRL_get_issuer(x), nmflag);
 				}
-
+			if (crlnumber == i)
+				{
+				ASN1_INTEGER *crlnum;
+				crlnum = X509_CRL_get_ext_d2i(x, NID_crl_number,
+							      NULL, NULL);
+				BIO_printf(bio_out,"crlNumber=");
+				if (crlnum)
+					{
+					i2a_ASN1_INTEGER(bio_out, crlnum);
+					ASN1_INTEGER_free(crlnum);
+					}
+				else
+					BIO_puts(bio_out, "<NONE>");
+				BIO_printf(bio_out,"\n");
+				}
 			if (hash == i)
 				{
 				BIO_printf(bio_out,"%08lx\n",
diff --git a/apps/dgst.c b/apps/dgst.c
index c5ecf93..9ebfc22 100644
--- a/apps/dgst.c
+++ b/apps/dgst.c
@@ -76,7 +76,7 @@
 
 int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
 	  EVP_PKEY *key, unsigned char *sigin, int siglen, const char *title,
-	  const char *file,BIO *bmd,const char *hmac_key);
+	  const char *file,BIO *bmd,const char *hmac_key, int non_fips_allow);
 
 int MAIN(int, char **);
 
@@ -84,7 +84,7 @@
 	{
 	ENGINE *e = NULL;
 	unsigned char *buf=NULL;
-	int i,err=0;
+	int i,err=1;
 	const EVP_MD *md=NULL,*m;
 	BIO *in=NULL,*inp;
 	BIO *bmd=NULL;
@@ -101,14 +101,16 @@
 	EVP_PKEY *sigkey = NULL;
 	unsigned char *sigbuf = NULL;
 	int siglen = 0;
+	unsigned int sig_flags = 0;
 	char *passargin = NULL, *passin = NULL;
 #ifndef OPENSSL_NO_ENGINE
 	char *engine=NULL;
 #endif
 	char *hmac_key=NULL;
+	int non_fips_allow = 0;
 
 	apps_startup();
-
+ERR_load_crypto_strings();
 	if ((buf=(unsigned char *)OPENSSL_malloc(BUFSIZE)) == NULL)
 		{
 		BIO_printf(bio_err,"out of memory\n");
@@ -167,6 +169,27 @@
 			keyfile=*(++argv);
 			do_verify = 1;
 			}
+		else if (strcmp(*argv,"-x931") == 0)
+			sig_flags = EVP_MD_CTX_FLAG_PAD_X931;
+		else if (strcmp(*argv,"-pss_saltlen") == 0)
+			{
+			int saltlen;
+			if (--argc < 1) break;
+			saltlen=atoi(*(++argv));
+			if (saltlen == -1)
+				sig_flags = EVP_MD_CTX_FLAG_PSS_MREC;
+			else if (saltlen == -2)
+				sig_flags = EVP_MD_CTX_FLAG_PSS_MDLEN;
+			else if (saltlen < -2 || saltlen >= 0xFFFE)
+				{
+				BIO_printf(bio_err, "Invalid PSS salt length %d\n", saltlen);
+				goto end;
+				}
+			else
+				sig_flags = saltlen;
+			sig_flags <<= 16;
+			sig_flags |= EVP_MD_CTX_FLAG_PAD_PSS;
+			}
 		else if (strcmp(*argv,"-signature") == 0)
 			{
 			if (--argc < 1) break;
@@ -190,6 +213,8 @@
 			out_bin = 1;
 		else if (strcmp(*argv,"-d") == 0)
 			debug=1;
+		else if (strcmp(*argv,"-non-fips-allow") == 0)
+			non_fips_allow=1;
 		else if (!strcmp(*argv,"-fips-fingerprint"))
 			hmac_key = "etaonrishdlcupfm";
 		else if (!strcmp(*argv,"-hmac"))
@@ -356,8 +381,20 @@
 			goto end;
 		}
 	}
-		
 
+	if (non_fips_allow)
+		{
+		EVP_MD_CTX *md_ctx;
+		BIO_get_md_ctx(bmd,&md_ctx);
+		EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+		}
+
+	if (sig_flags)
+		{
+		EVP_MD_CTX *md_ctx;
+		BIO_get_md_ctx(bmd,&md_ctx);
+		EVP_MD_CTX_set_flags(md_ctx, sig_flags);
+		}
 
 	/* we use md as a filter, reading from 'in' */
 	if (!BIO_set_md(bmd,md))
@@ -373,11 +410,12 @@
 		{
 		BIO_set_fp(in,stdin,BIO_NOCLOSE);
 		err=do_fp(out, buf,inp,separator, out_bin, sigkey, sigbuf,
-			  siglen,"","(stdin)",bmd,hmac_key);
+			  siglen,"","(stdin)",bmd,hmac_key,non_fips_allow);
 		}
 	else
 		{
 		name=OBJ_nid2sn(md->type);
+		err = 0;
 		for (i=0; i<argc; i++)
 			{
 			char *tmp,*tofree=NULL;
@@ -399,7 +437,7 @@
 			else
 				tmp="";
 			r=do_fp(out,buf,inp,separator,out_bin,sigkey,sigbuf,
-				siglen,tmp,argv[i],bmd,hmac_key);
+				siglen,tmp,argv[i],bmd,hmac_key,non_fips_allow);
 			if(r)
 			    err=r;
 			if(tofree)
@@ -426,7 +464,7 @@
 
 int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
 	  EVP_PKEY *key, unsigned char *sigin, int siglen, const char *title,
-	  const char *file,BIO *bmd,const char *hmac_key)
+	  const char *file,BIO *bmd,const char *hmac_key,int non_fips_allow)
 	{
 	unsigned int len;
 	int i;
diff --git a/apps/dsa.c b/apps/dsa.c
index 9e10303..cbc1fe3 100644
--- a/apps/dsa.c
+++ b/apps/dsa.c
@@ -96,9 +96,7 @@
 
 int MAIN(int argc, char **argv)
 	{
-#ifndef OPENSSL_NO_ENGINE
 	ENGINE *e = NULL;
-#endif
 	int ret=1;
 	DSA *dsa=NULL;
 	int i,badops=0;
@@ -240,37 +238,27 @@
 		goto end;
 	}
 
-	in=BIO_new(BIO_s_file());
 	out=BIO_new(BIO_s_file());
-	if ((in == NULL) || (out == NULL))
+	if (out == NULL)
 		{
 		ERR_print_errors(bio_err);
 		goto end;
 		}
 
-	if (infile == NULL)
-		BIO_set_fp(in,stdin,BIO_NOCLOSE);
-	else
-		{
-		if (BIO_read_filename(in,infile) <= 0)
-			{
-			perror(infile);
-			goto end;
-			}
-		}
-
 	BIO_printf(bio_err,"read DSA key\n");
-	if	(informat == FORMAT_ASN1) {
-		if(pubin) dsa=d2i_DSA_PUBKEY_bio(in,NULL);
-		else dsa=d2i_DSAPrivateKey_bio(in,NULL);
-	} else if (informat == FORMAT_PEM) {
-		if(pubin) dsa=PEM_read_bio_DSA_PUBKEY(in,NULL, NULL, NULL);
-		else dsa=PEM_read_bio_DSAPrivateKey(in,NULL,NULL,passin);
-	} else
-		{
-		BIO_printf(bio_err,"bad input format specified for key\n");
-		goto end;
-		}
+	{
+		EVP_PKEY	*pkey;
+		if (pubin)
+			pkey = load_pubkey(bio_err, infile, informat, 1,
+				passin, e, "Public Key");
+		else
+			pkey = load_key(bio_err, infile, informat, 1,
+				passin, e, "Private Key");
+
+		if (pkey != NULL)
+		dsa = pkey == NULL ? NULL : EVP_PKEY_get1_DSA(pkey);
+		EVP_PKEY_free(pkey);
+	}
 	if (dsa == NULL)
 		{
 		BIO_printf(bio_err,"unable to load Key\n");
diff --git a/apps/enc.c b/apps/enc.c
index a41ea80..f4f9a4c 100644
--- a/apps/enc.c
+++ b/apps/enc.c
@@ -127,6 +127,7 @@
 	char *engine = NULL;
 #endif
 	const EVP_MD *dgst=NULL;
+	int non_fips_allow = 0;
 
 	apps_startup();
 
@@ -261,6 +262,8 @@
 			if (--argc < 1) goto bad;
 			md= *(++argv);
 			}
+		else if (strcmp(*argv,"-non-fips-allow") == 0)
+			non_fips_allow = 1;
 		else if	((argv[0][0] == '-') &&
 			((c=EVP_get_cipherbyname(&(argv[0][1]))) != NULL))
 			{
@@ -314,7 +317,10 @@
 
 	if (dgst == NULL)
 		{
-		dgst = EVP_md5();
+		if (in_FIPS_mode)
+			dgst = EVP_sha1();
+		else
+			dgst = EVP_md5();
 		}
 
 	if (bufsize != NULL)
@@ -527,7 +533,8 @@
 			BIO_printf(bio_err,"invalid hex iv value\n");
 			goto end;
 			}
-		if ((hiv == NULL) && (str == NULL))
+		if ((hiv == NULL) && (str == NULL)
+		    && EVP_CIPHER_iv_length(cipher) != 0)
 			{
 			/* No IV was explicitly set and no IV was generated
 			 * during EVP_BytesToKey. Hence the IV is undefined,
@@ -549,6 +556,11 @@
 		 */
 
 		BIO_get_cipher_ctx(benc, &ctx);
+
+		if (non_fips_allow)
+			EVP_CIPHER_CTX_set_flags(ctx,
+				EVP_CIPH_FLAG_NON_FIPS_ALLOW);
+
 		if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc))
 			{
 			BIO_printf(bio_err, "Error setting cipher %s\n",
diff --git a/apps/engine.c b/apps/engine.c
index 25c8617..17bd81f 100644
--- a/apps/engine.c
+++ b/apps/engine.c
@@ -56,7 +56,6 @@
  *
  */
 
-#ifndef OPENSSL_NO_ENGINE
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -66,6 +65,7 @@
 #endif
 #include "apps.h"
 #include <openssl/err.h>
+#ifndef OPENSSL_NO_ENGINE
 #include <openssl/engine.h>
 #include <openssl/ssl.h>
 
@@ -252,7 +252,7 @@
                         /* Now decide on the output */
                         if(xpos == 0)
                                 /* Do an indent */
-                                xpos = BIO_printf(bio_out, indent);
+                                xpos = BIO_puts(bio_out, indent);
                         else
                                 /* Otherwise prepend a ", " */
                                 xpos += BIO_printf(bio_out, ", ");
@@ -263,7 +263,7 @@
 					(xpos + (int)strlen(name) > line_wrap))
                                         {
                                         BIO_printf(bio_out, "\n");
-                                        xpos = BIO_printf(bio_out, indent);
+                                        xpos = BIO_puts(bio_out, indent);
                                         }
                                 xpos += BIO_printf(bio_out, "%s", name);
                                 }
diff --git a/apps/genpkey.c b/apps/genpkey.c
new file mode 100644
index 0000000..6dfda08
--- /dev/null
+++ b/apps/genpkey.c
@@ -0,0 +1,440 @@
+/* apps/genpkey.c */
+/* Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
+
+static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx,
+				const char *file, ENGINE *e);
+static int genpkey_cb(EVP_PKEY_CTX *ctx);
+
+#define PROG genpkey_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	ENGINE *e = NULL;
+	char **args, *outfile = NULL;
+	char *passarg = NULL;
+	BIO *in = NULL, *out = NULL;
+	const EVP_CIPHER *cipher = NULL;
+	int outformat;
+	int text = 0;
+	EVP_PKEY *pkey=NULL;
+	EVP_PKEY_CTX *ctx = NULL;
+	char *pass = NULL;
+	int badarg = 0;
+	int ret = 1, rv;
+
+	int do_param = 0;
+
+	if (bio_err == NULL)
+		bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	outformat=FORMAT_PEM;
+
+	ERR_load_crypto_strings();
+	OpenSSL_add_all_algorithms();
+	args = argv + 1;
+	while (!badarg && *args && *args[0] == '-')
+		{
+		if (!strcmp(*args,"-outform"))
+			{
+			if (args[1])
+				{
+				args++;
+				outformat=str2fmt(*args);
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args,"-pass"))
+			{
+			if (!args[1]) goto bad;
+			passarg= *(++args);
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*args,"-engine") == 0)
+			{
+			if (!args[1])
+				goto bad;
+        		e = setup_engine(bio_err, *(++args), 0);
+			}
+#endif
+		else if (!strcmp (*args, "-paramfile"))
+			{
+			if (!args[1])
+				goto bad;
+			args++;
+			if (do_param == 1)
+				goto bad;
+			if (!init_keygen_file(bio_err, &ctx, *args, e))
+				goto end;
+			}
+		else if (!strcmp (*args, "-out"))
+			{
+			if (args[1])
+				{
+				args++;
+				outfile = *args;
+				}
+			else badarg = 1;
+			}
+		else if (strcmp(*args,"-algorithm") == 0)
+			{
+			if (!args[1])
+				goto bad;
+			if (!init_gen_str(bio_err, &ctx, *(++args),e, do_param))
+				goto end;
+			}
+		else if (strcmp(*args,"-pkeyopt") == 0)
+			{
+			if (!args[1])
+				goto bad;
+			if (!ctx)
+				{
+				BIO_puts(bio_err, "No keytype specified\n");
+				goto bad;
+				}
+			else if (pkey_ctrl_string(ctx, *(++args)) <= 0)
+				{
+				BIO_puts(bio_err, "parameter setting error\n");
+				ERR_print_errors(bio_err);
+				goto end;
+				}
+			}
+		else if (strcmp(*args,"-genparam") == 0)
+			{
+			if (ctx)
+				goto bad;
+			do_param = 1;
+			}
+		else if (strcmp(*args,"-text") == 0)
+			text=1;
+		else
+			{
+			cipher = EVP_get_cipherbyname(*args + 1);
+			if (!cipher)
+				{
+				BIO_printf(bio_err, "Unknown cipher %s\n",
+								*args + 1);
+				badarg = 1;
+				}
+			if (do_param == 1)
+				badarg = 1;
+			}
+		args++;
+		}
+
+	if (!ctx)
+		badarg = 1;
+
+	if (badarg)
+		{
+		bad:
+		BIO_printf(bio_err, "Usage: genpkey [options]\n");
+		BIO_printf(bio_err, "where options may be\n");
+		BIO_printf(bio_err, "-out file          output file\n");
+		BIO_printf(bio_err, "-outform X         output format (DER or PEM)\n");
+		BIO_printf(bio_err, "-pass arg          output file pass phrase source\n");
+		BIO_printf(bio_err, "-<cipher>          use cipher <cipher> to encrypt the key\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err, "-engine e          use engine e, possibly a hardware device.\n");
+#endif
+		BIO_printf(bio_err, "-paramfile file    parameters file\n");
+		BIO_printf(bio_err, "-algorithm alg     the public key algorithm\n");
+		BIO_printf(bio_err, "-pkeyopt opt:value set the public key algorithm option <opt>\n"
+				            "                   to value <value>\n");
+		BIO_printf(bio_err, "-genparam          generate parameters, not key\n");
+		BIO_printf(bio_err, "-text              print the in text\n");
+		BIO_printf(bio_err, "NB: options order may be important!  See the manual page.\n");
+		goto end;
+		}
+
+	if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
+		{
+		BIO_puts(bio_err, "Error getting password\n");
+		goto end;
+		}
+
+	if (outfile)
+		{
+		if (!(out = BIO_new_file (outfile, "wb")))
+			{
+			BIO_printf(bio_err,
+				 "Can't open output file %s\n", outfile);
+			goto end;
+			}
+		}
+	else
+		{
+		out = BIO_new_fp (stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+			{
+			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+			out = BIO_push(tmpbio, out);
+			}
+#endif
+		}
+
+	EVP_PKEY_CTX_set_cb(ctx, genpkey_cb);
+	EVP_PKEY_CTX_set_app_data(ctx, bio_err);
+
+	if (do_param)
+		{
+		if (EVP_PKEY_paramgen(ctx, &pkey) <= 0)
+			{
+			BIO_puts(bio_err, "Error generating parameters\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+	else
+		{
+		if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
+			{
+			BIO_puts(bio_err, "Error generating key\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		}
+
+	if (do_param)
+		rv = PEM_write_bio_Parameters(out, pkey);
+	else if (outformat == FORMAT_PEM) 
+		rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0,
+								NULL, pass);
+	else if (outformat == FORMAT_ASN1)
+		rv = i2d_PrivateKey_bio(out, pkey);
+	else
+		{
+		BIO_printf(bio_err, "Bad format specified for key\n");
+		goto end;
+		}
+
+	if (rv <= 0)
+		{
+		BIO_puts(bio_err, "Error writing key\n");
+		ERR_print_errors(bio_err);
+		}
+
+	if (text)
+		{
+		if (do_param)
+			rv = EVP_PKEY_print_params(out, pkey, 0, NULL);
+		else
+			rv = EVP_PKEY_print_private(out, pkey, 0, NULL);
+
+		if (rv <= 0)
+			{
+			BIO_puts(bio_err, "Error printing key\n");
+			ERR_print_errors(bio_err);
+			}
+		}
+
+	ret = 0;
+
+	end:
+	if (pkey)
+		EVP_PKEY_free(pkey);
+	if (ctx)
+		EVP_PKEY_CTX_free(ctx);
+	if (out)
+		BIO_free_all(out);
+	BIO_free(in);
+	if (pass)
+		OPENSSL_free(pass);
+
+	return ret;
+	}
+
+static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx,
+				const char *file, ENGINE *e)
+	{
+	BIO *pbio;
+	EVP_PKEY *pkey = NULL;
+	EVP_PKEY_CTX *ctx = NULL;
+	if (*pctx)
+		{
+		BIO_puts(err, "Parameters already set!\n");
+		return 0;
+		}
+
+	pbio = BIO_new_file(file, "r");
+	if (!pbio)
+		{
+		BIO_printf(err, "Can't open parameter file %s\n", file);
+		return 0;
+		}
+
+	pkey = PEM_read_bio_Parameters(pbio, NULL);
+	BIO_free(pbio);
+
+	if (!pkey)
+		{
+		BIO_printf(bio_err, "Error reading parameter file %s\n", file);
+		return 0;
+		}
+
+	ctx = EVP_PKEY_CTX_new(pkey, e);
+	if (!ctx)
+		goto err;
+	if (EVP_PKEY_keygen_init(ctx) <= 0)
+		goto err;
+	EVP_PKEY_free(pkey);
+	*pctx = ctx;
+	return 1;
+
+	err:
+	BIO_puts(err, "Error initializing context\n");
+	ERR_print_errors(err);
+	if (ctx)
+		EVP_PKEY_CTX_free(ctx);
+	if (pkey)
+		EVP_PKEY_free(pkey);
+	return 0;
+
+	}
+
+int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx,
+			const char *algname, ENGINE *e, int do_param)
+	{
+	EVP_PKEY_CTX *ctx = NULL;
+	const EVP_PKEY_ASN1_METHOD *ameth;
+	ENGINE *tmpeng = NULL;
+	int pkey_id;
+
+	if (*pctx)
+		{
+		BIO_puts(err, "Algorithm already set!\n");
+		return 0;
+		}
+
+	ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1);
+
+#ifndef OPENSSL_NO_ENGINE
+	if (!ameth && e)
+		ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1);
+#endif
+
+	if (!ameth)
+		{
+		BIO_printf(bio_err, "Algorithm %s not found\n", algname);
+		return 0;
+		}
+
+	ERR_clear_error();
+
+	EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
+#ifndef OPENSSL_NO_ENGINE
+	if (tmpeng)
+		ENGINE_finish(tmpeng);
+#endif
+	ctx = EVP_PKEY_CTX_new_id(pkey_id, e);
+
+	if (!ctx)
+		goto err;
+	if (do_param)
+		{
+		if (EVP_PKEY_paramgen_init(ctx) <= 0)
+			goto err;
+		}
+	else
+		{
+		if (EVP_PKEY_keygen_init(ctx) <= 0)
+			goto err;
+		}
+
+	*pctx = ctx;
+	return 1;
+
+	err:
+	BIO_printf(err, "Error initializing %s context\n", algname);
+	ERR_print_errors(err);
+	if (ctx)
+		EVP_PKEY_CTX_free(ctx);
+	return 0;
+
+	}
+
+static int genpkey_cb(EVP_PKEY_CTX *ctx)
+	{
+	char c='*';
+	BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
+	int p;
+	p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
+	if (p == 0) c='.';
+	if (p == 1) c='+';
+	if (p == 2) c='*';
+	if (p == 3) c='\n';
+	BIO_write(b,&c,1);
+	(void)BIO_flush(b);
+#ifdef LINT
+	p=n;
+#endif
+	return 1;
+	}
diff --git a/apps/genrsa.c b/apps/genrsa.c
index 1599bb7..fdc0d4a 100644
--- a/apps/genrsa.c
+++ b/apps/genrsa.c
@@ -95,6 +95,7 @@
 	int ret=1;
 	int i,num=DEFBITS;
 	long l;
+	int use_x931 = 0;
 	const EVP_CIPHER *enc=NULL;
 	unsigned long f4=RSA_F4;
 	char *outfile=NULL;
@@ -138,6 +139,8 @@
 			f4=3;
 		else if (strcmp(*argv,"-F4") == 0 || strcmp(*argv,"-f4") == 0)
 			f4=RSA_F4;
+		else if (strcmp(*argv,"-x931") == 0)
+			use_x931 = 1;
 #ifndef OPENSSL_NO_ENGINE
 		else if (strcmp(*argv,"-engine") == 0)
 			{
@@ -266,7 +269,17 @@
 	BIO_printf(bio_err,"Generating RSA private key, %d bit long modulus\n",
 		num);
 
-	if(!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, &cb))
+	if (use_x931)
+		{
+		BIGNUM *pubexp;
+		pubexp = BN_new();
+		if (!BN_set_word(pubexp, f4))
+			goto err;
+		if (!RSA_X931_generate_key_ex(rsa, num, pubexp, &cb))
+			goto err;
+		BN_free(pubexp);
+		}
+	else if(!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, &cb))
 		goto err;
 		
 	app_RAND_write_file(NULL, bio_err);
diff --git a/apps/makeapps.com b/apps/makeapps.com
index 826ab5b..0580a1f 100644
--- a/apps/makeapps.com
+++ b/apps/makeapps.com
@@ -142,7 +142,7 @@
 	      "RSA;RSAUTL;DSA;DSAPARAM;EC;ECPARAM;"+-
 	      "X509;GENRSA;GENDSA;S_SERVER;S_CLIENT;SPEED;"+-
 	      "S_TIME;APPS;S_CB;S_SOCKET;APP_RAND;VERSION;SESS_ID;"+-
-	      "CIPHERS;NSEQ;PKCS12;PKCS8;SPKAC;SMIME;CMS;RAND;ENGINE;OCSP;PRIME"
+	      "CIPHERS;NSEQ;PKCS12;PKCS8;SPKAC;SMIME;RAND;ENGINE;OCSP;PRIME"
 $ TCPIP_PROGRAMS = ",,"
 $ IF COMPILER .EQS. "VAXC" THEN -
      TCPIP_PROGRAMS = ",OPENSSL,"
diff --git a/apps/nseq.c b/apps/nseq.c
index dc71d45..e3c4dba 100644
--- a/apps/nseq.c
+++ b/apps/nseq.c
@@ -1,5 +1,5 @@
 /* nseq.c */
-/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/apps/ocsp.c b/apps/ocsp.c
index 1001f3b..251044d 100644
--- a/apps/ocsp.c
+++ b/apps/ocsp.c
@@ -1,5 +1,5 @@
 /* ocsp.c */
-/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/apps/openssl.c b/apps/openssl.c
index 47aee5b..7d2b476 100644
--- a/apps/openssl.c
+++ b/apps/openssl.c
@@ -147,6 +147,7 @@
 #ifdef MONOLITH
 CONF *config=NULL;
 BIO *bio_err=NULL;
+int in_FIPS_mode=0;
 #endif
 
 
@@ -232,6 +233,19 @@
 	arg.data=NULL;
 	arg.count=0;
 
+	in_FIPS_mode = 0;
+
+#ifdef OPENSSL_FIPS
+	if(getenv("OPENSSL_FIPS")) {
+		if (!FIPS_mode_set(1)) {
+			ERR_load_crypto_strings();
+			ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE));
+			EXIT(1);
+		}
+		in_FIPS_mode = 1;
+		}
+#endif
+
 	if (bio_err == NULL)
 		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
 			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
diff --git a/apps/pkcs12.c b/apps/pkcs12.c
index 7c71b1a..248bc11 100644
--- a/apps/pkcs12.c
+++ b/apps/pkcs12.c
@@ -1,5 +1,5 @@
 /* pkcs12.c */
-/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
  * project.
  */
 /* ====================================================================
@@ -100,6 +100,7 @@
     char **args;
     char *name = NULL;
     char *csp_name = NULL;
+    int add_lmk = 0;
     PKCS12 *p12 = NULL;
     char pass[50], macpass[50];
     int export_cert = 0;
@@ -110,7 +111,7 @@
     int maciter = PKCS12_DEFAULT_ITER;
     int twopass = 0;
     int keytype = 0;
-    int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
+    int cert_pbe;
     int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
     int ret = 1;
     int macver = 1;
@@ -127,6 +128,13 @@
 
     apps_startup();
 
+#ifdef OPENSSL_FIPS
+    if (FIPS_mode())
+	cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+    else
+#endif
+    cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
+
     enc = EVP_des_ede3_cbc();
     if (bio_err == NULL ) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
 
@@ -224,7 +232,9 @@
 			args++;	
 			name = *args;
 		    } else badarg = 1;
-		} else if (!strcmp (*args, "-CSP")) {
+		} else if (!strcmp (*args, "-LMK"))
+			add_lmk = 1;
+		else if (!strcmp (*args, "-CSP")) {
 		    if (args[1]) {
 			args++;	
 			csp_name = *args;
@@ -338,6 +348,8 @@
 	BIO_printf(bio_err,  "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
 	BIO_printf(bio_err,  "              load the file (or the files in the directory) into\n");
 	BIO_printf(bio_err,  "              the random number generator\n");
+  	BIO_printf(bio_err,  "-CSP name     Microsoft CSP name\n");
+ 	BIO_printf(bio_err,  "-LMK          Add local machine keyset attribute to private key\n");
     	goto end;
     }
 
@@ -562,7 +574,9 @@
 	if (csp_name && key)
 		EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name,
 				MBSTRING_ASC, (unsigned char *)csp_name, -1);
-		
+
+	if (add_lmk && key)
+		EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1);
 
 #ifdef CRYPTO_MDEBUG
 	CRYPTO_pop_info();
diff --git a/apps/pkcs8.c b/apps/pkcs8.c
index d508544..9633a14 100644
--- a/apps/pkcs8.c
+++ b/apps/pkcs8.c
@@ -1,5 +1,5 @@
 /* pkcs8.c */
-/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
  * project 1999-2004.
  */
 /* ====================================================================
diff --git a/apps/pkey.c b/apps/pkey.c
new file mode 100644
index 0000000..17e6702
--- /dev/null
+++ b/apps/pkey.c
@@ -0,0 +1,284 @@
+/* apps/pkey.c */
+/* Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+#define PROG pkey_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	ENGINE *e = NULL;
+	char **args, *infile = NULL, *outfile = NULL;
+	char *passargin = NULL, *passargout = NULL;
+	BIO *in = NULL, *out = NULL;
+	const EVP_CIPHER *cipher = NULL;
+	int informat, outformat;
+	int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0;
+	EVP_PKEY *pkey=NULL;
+	char *passin = NULL, *passout = NULL;
+	int badarg = 0;
+#ifndef OPENSSL_NO_ENGINE
+	char *engine=NULL;
+#endif
+	int ret = 1;
+
+	if (bio_err == NULL)
+		bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	informat=FORMAT_PEM;
+	outformat=FORMAT_PEM;
+
+	ERR_load_crypto_strings();
+	OpenSSL_add_all_algorithms();
+	args = argv + 1;
+	while (!badarg && *args && *args[0] == '-')
+		{
+		if (!strcmp(*args,"-inform"))
+			{
+			if (args[1])
+				{
+				args++;
+				informat=str2fmt(*args);
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args,"-outform"))
+			{
+			if (args[1])
+				{
+				args++;
+				outformat=str2fmt(*args);
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp(*args,"-passin"))
+			{
+			if (!args[1]) goto bad;
+			passargin= *(++args);
+			}
+		else if (!strcmp(*args,"-passout"))
+			{
+			if (!args[1]) goto bad;
+			passargout= *(++args);
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*args,"-engine") == 0)
+			{
+			if (!args[1]) goto bad;
+			engine= *(++args);
+			}
+#endif
+		else if (!strcmp (*args, "-in"))
+			{
+			if (args[1])
+				{
+				args++;
+				infile = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp (*args, "-out"))
+			{
+			if (args[1])
+				{
+				args++;
+				outfile = *args;
+				}
+			else badarg = 1;
+			}
+		else if (strcmp(*args,"-pubin") == 0)
+			{
+			pubin=1;
+			pubout=1;
+			pubtext=1;
+			}
+		else if (strcmp(*args,"-pubout") == 0)
+			pubout=1;
+		else if (strcmp(*args,"-text_pub") == 0)
+			{
+			pubtext=1;
+			text=1;
+			}
+		else if (strcmp(*args,"-text") == 0)
+			text=1;
+		else if (strcmp(*args,"-noout") == 0)
+			noout=1;
+		else
+			{
+			cipher = EVP_get_cipherbyname(*args + 1);
+			if (!cipher)
+				{
+				BIO_printf(bio_err, "Unknown cipher %s\n",
+								*args + 1);
+				badarg = 1;
+				}
+			}
+		args++;
+		}
+
+	if (badarg)
+		{
+		bad:
+		BIO_printf(bio_err, "Usage pkey [options]\n");
+		BIO_printf(bio_err, "where options are\n");
+		BIO_printf(bio_err, "-in file        input file\n");
+		BIO_printf(bio_err, "-inform X       input format (DER or PEM)\n");
+		BIO_printf(bio_err, "-passin arg     input file pass phrase source\n");
+		BIO_printf(bio_err, "-outform X      output format (DER or PEM)\n");
+		BIO_printf(bio_err, "-out file       output file\n");
+		BIO_printf(bio_err, "-passout arg    output file pass phrase source\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err, "-engine e       use engine e, possibly a hardware device.\n");
+#endif
+		return 1;
+		}
+
+#ifndef OPENSSL_NO_ENGINE
+        e = setup_engine(bio_err, engine, 0);
+#endif
+
+	if (!app_passwd(bio_err, passargin, passargout, &passin, &passout))
+		{
+		BIO_printf(bio_err, "Error getting passwords\n");
+		goto end;
+		}
+
+	if (outfile)
+		{
+		if (!(out = BIO_new_file (outfile, "wb")))
+			{
+			BIO_printf(bio_err,
+				 "Can't open output file %s\n", outfile);
+			goto end;
+			}
+		}
+	else
+		{
+		out = BIO_new_fp (stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+			{
+			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+			out = BIO_push(tmpbio, out);
+			}
+#endif
+		}
+
+	if (pubin)
+		pkey = load_pubkey(bio_err, infile, informat, 1,
+			passin, e, "Public Key");
+	else
+		pkey = load_key(bio_err, infile, informat, 1,
+			passin, e, "key");
+	if (!pkey)
+		goto end;
+
+	if (!noout)
+		{
+		if (outformat == FORMAT_PEM) 
+			{
+			if (pubout)
+				PEM_write_bio_PUBKEY(out,pkey);
+			else
+				PEM_write_bio_PrivateKey(out, pkey, cipher,
+							NULL, 0, NULL, passout);
+			}
+		else if (outformat == FORMAT_ASN1)
+			{
+			if (pubout)
+				i2d_PUBKEY_bio(out, pkey);
+			else
+				i2d_PrivateKey_bio(out, pkey);
+			}
+		else
+			{
+			BIO_printf(bio_err, "Bad format specified for key\n");
+			goto end;
+			}
+
+		}
+
+	if (text)
+		{
+		if (pubtext)
+			EVP_PKEY_print_public(out, pkey, 0, NULL);
+		else
+			EVP_PKEY_print_private(out, pkey, 0, NULL);
+		}
+
+	ret = 0;
+
+	end:
+	EVP_PKEY_free(pkey);
+	BIO_free_all(out);
+	BIO_free(in);
+	if (passin)
+		OPENSSL_free(passin);
+	if (passout)
+		OPENSSL_free(passout);
+
+	return ret;
+	}
diff --git a/apps/pkeyparam.c b/apps/pkeyparam.c
new file mode 100644
index 0000000..4319eb4
--- /dev/null
+++ b/apps/pkeyparam.c
@@ -0,0 +1,201 @@
+/* apps/pkeyparam.c */
+/* Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+#define PROG pkeyparam_main
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	char **args, *infile = NULL, *outfile = NULL;
+	BIO *in = NULL, *out = NULL;
+	int text = 0, noout = 0;
+	EVP_PKEY *pkey=NULL;
+	int badarg = 0;
+#ifndef OPENSSL_NO_ENGINE
+	ENGINE *e = NULL;
+	char *engine=NULL;
+#endif
+	int ret = 1;
+
+	if (bio_err == NULL)
+		bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+
+	ERR_load_crypto_strings();
+	OpenSSL_add_all_algorithms();
+	args = argv + 1;
+	while (!badarg && *args && *args[0] == '-')
+		{
+		if (!strcmp (*args, "-in"))
+			{
+			if (args[1])
+				{
+				args++;
+				infile = *args;
+				}
+			else badarg = 1;
+			}
+		else if (!strcmp (*args, "-out"))
+			{
+			if (args[1])
+				{
+				args++;
+				outfile = *args;
+				}
+			else badarg = 1;
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if (strcmp(*args,"-engine") == 0)
+			{
+			if (!args[1]) goto bad;
+			engine= *(++args);
+			}
+#endif
+
+		else if (strcmp(*args,"-text") == 0)
+			text=1;
+		else if (strcmp(*args,"-noout") == 0)
+			noout=1;
+		args++;
+		}
+
+	if (badarg)
+		{
+#ifndef OPENSSL_NO_ENGINE
+		bad:
+#endif
+		BIO_printf(bio_err, "Usage pkeyparam [options]\n");
+		BIO_printf(bio_err, "where options are\n");
+		BIO_printf(bio_err, "-in file        input file\n");
+		BIO_printf(bio_err, "-out file       output file\n");
+		BIO_printf(bio_err, "-text           print parameters as text\n");
+		BIO_printf(bio_err, "-noout          don't output encoded parameters\n");
+#ifndef OPENSSL_NO_ENGINE
+		BIO_printf(bio_err, "-engine e       use engine e, possibly a hardware device.\n");
+#endif
+		return 1;
+		}
+
+#ifndef OPENSSL_NO_ENGINE
+        e = setup_engine(bio_err, engine, 0);
+#endif
+
+	if (infile)
+		{
+		if (!(in = BIO_new_file (infile, "r")))
+			{
+			BIO_printf(bio_err,
+				 "Can't open input file %s\n", infile);
+			goto end;
+			}
+		}
+	else
+		in = BIO_new_fp (stdin, BIO_NOCLOSE);
+
+	if (outfile)
+		{
+		if (!(out = BIO_new_file (outfile, "w")))
+			{
+			BIO_printf(bio_err,
+				 "Can't open output file %s\n", outfile);
+			goto end;
+			}
+		}
+	else
+		{
+		out = BIO_new_fp (stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+			{
+			BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+			out = BIO_push(tmpbio, out);
+			}
+#endif
+		}
+
+	pkey = PEM_read_bio_Parameters(in, NULL);
+	if (!pkey)
+		{
+		BIO_printf(bio_err, "Error reading paramters\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (!noout)
+		PEM_write_bio_Parameters(out,pkey);
+
+	if (text)
+		EVP_PKEY_print_params(out, pkey, 0, NULL);
+
+	ret = 0;
+
+	end:
+	EVP_PKEY_free(pkey);
+	BIO_free_all(out);
+	BIO_free(in);
+
+	return ret;
+	}
diff --git a/apps/pkeyutl.c b/apps/pkeyutl.c
new file mode 100644
index 0000000..b808e1e
--- /dev/null
+++ b/apps/pkeyutl.c
@@ -0,0 +1,570 @@
+/* Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+
+#include "apps.h"
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+
+#define KEY_PRIVKEY	1
+#define KEY_PUBKEY	2
+#define KEY_CERT	3
+
+static void usage(void);
+
+#undef PROG
+
+#define PROG pkeyutl_main
+
+static EVP_PKEY_CTX *init_ctx(int *pkeysize,
+				char *keyfile, int keyform, int key_type,
+				char *passargin, int pkey_op, ENGINE *e);
+
+static int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform,
+							const char *file);
+
+static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
+		unsigned char *out, size_t *poutlen,
+		unsigned char *in, size_t inlen);
+
+int MAIN(int argc, char **);
+
+int MAIN(int argc, char **argv)
+{
+	BIO *in = NULL, *out = NULL;
+	char *infile = NULL, *outfile = NULL, *sigfile = NULL;
+	ENGINE *e = NULL;
+	int pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY;
+	int keyform = FORMAT_PEM, peerform = FORMAT_PEM;
+	char badarg = 0, rev = 0;
+	char hexdump = 0, asn1parse = 0;
+	EVP_PKEY_CTX *ctx = NULL;
+	char *passargin = NULL;
+	int keysize = -1;
+
+	unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL;
+	size_t buf_outlen;
+	int buf_inlen = 0, siglen = -1;
+
+	int ret = 1, rv = -1;
+
+	argc--;
+	argv++;
+
+	if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+	if (!load_config(bio_err, NULL))
+		goto end;
+	ERR_load_crypto_strings();
+	OpenSSL_add_all_algorithms();
+	
+	while(argc >= 1)
+		{
+		if (!strcmp(*argv,"-in"))
+			{
+			if (--argc < 1) badarg = 1;
+                        infile= *(++argv);
+			}
+		else if (!strcmp(*argv,"-out"))
+			{
+			if (--argc < 1) badarg = 1;
+			outfile= *(++argv);
+			}
+		else if (!strcmp(*argv,"-sigfile"))
+			{
+			if (--argc < 1) badarg = 1;
+			sigfile= *(++argv);
+			}
+		else if(!strcmp(*argv, "-inkey"))
+			{
+			if (--argc < 1)
+				badarg = 1;
+			else
+				{
+				ctx = init_ctx(&keysize,
+						*(++argv), keyform, key_type,
+						passargin, pkey_op, e);
+				if (!ctx)
+					{
+					BIO_puts(bio_err,
+						"Error initializing context\n");
+					ERR_print_errors(bio_err);
+					badarg = 1;
+					}
+				}
+			}
+		else if (!strcmp(*argv,"-peerkey"))
+			{
+			if (--argc < 1)
+				badarg = 1;
+			else if (!setup_peer(bio_err, ctx, peerform, *(++argv)))
+				badarg = 1;
+			}
+		else if (!strcmp(*argv,"-passin"))
+			{
+			if (--argc < 1) badarg = 1;
+			passargin= *(++argv);
+			}
+		else if (strcmp(*argv,"-peerform") == 0)
+			{
+			if (--argc < 1) badarg = 1;
+			peerform=str2fmt(*(++argv));
+			}
+		else if (strcmp(*argv,"-keyform") == 0)
+			{
+			if (--argc < 1) badarg = 1;
+			keyform=str2fmt(*(++argv));
+			}
+#ifndef OPENSSL_NO_ENGINE
+		else if(!strcmp(*argv, "-engine"))
+			{
+			if (--argc < 1)
+				badarg = 1;
+			else
+				e = setup_engine(bio_err, *(++argv), 0);
+			}
+#endif
+		else if(!strcmp(*argv, "-pubin"))
+			key_type = KEY_PUBKEY;
+		else if(!strcmp(*argv, "-certin"))
+			key_type = KEY_CERT;
+		else if(!strcmp(*argv, "-asn1parse"))
+			asn1parse = 1;
+		else if(!strcmp(*argv, "-hexdump"))
+			hexdump = 1;
+		else if(!strcmp(*argv, "-sign"))
+			pkey_op = EVP_PKEY_OP_SIGN;
+		else if(!strcmp(*argv, "-verify"))
+			pkey_op = EVP_PKEY_OP_VERIFY;
+		else if(!strcmp(*argv, "-verifyrecover"))
+			pkey_op = EVP_PKEY_OP_VERIFYRECOVER;
+		else if(!strcmp(*argv, "-rev"))
+			rev = 1;
+		else if(!strcmp(*argv, "-encrypt"))
+			pkey_op = EVP_PKEY_OP_ENCRYPT;
+		else if(!strcmp(*argv, "-decrypt"))
+			pkey_op = EVP_PKEY_OP_DECRYPT;
+		else if(!strcmp(*argv, "-derive"))
+			pkey_op = EVP_PKEY_OP_DERIVE;
+		else if (strcmp(*argv,"-pkeyopt") == 0)
+			{
+			if (--argc < 1)
+				badarg = 1;
+			else if (!ctx)
+				{
+				BIO_puts(bio_err,
+					"-pkeyopt command before -inkey\n");
+				badarg = 1;
+				}
+			else if (pkey_ctrl_string(ctx, *(++argv)) <= 0)
+				{
+				BIO_puts(bio_err, "parameter setting error\n");
+				ERR_print_errors(bio_err);
+				goto end;
+				}
+			}
+		else badarg = 1;
+		if(badarg)
+			{
+			usage();
+			goto end;
+			}
+		argc--;
+		argv++;
+		}
+
+	if (!ctx)
+		{
+		usage();
+		goto end;
+		}
+
+	if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY))
+		{
+		BIO_puts(bio_err, "Signature file specified for non verify\n");
+		goto end;
+		}
+
+	if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY))
+		{
+		BIO_puts(bio_err, "No signature file specified for verify\n");
+		goto end;
+		}
+
+/* FIXME: seed PRNG only if needed */
+	app_RAND_load_file(NULL, bio_err, 0);
+
+	if (pkey_op != EVP_PKEY_OP_DERIVE)
+		{
+		if(infile)
+			{
+			if(!(in = BIO_new_file(infile, "rb")))
+				{
+				BIO_puts(bio_err,
+					"Error Opening Input File\n");
+				ERR_print_errors(bio_err);	
+				goto end;
+				}
+			}
+		else
+			in = BIO_new_fp(stdin, BIO_NOCLOSE);
+		}
+
+	if(outfile)
+		{
+		if(!(out = BIO_new_file(outfile, "wb")))
+			{
+			BIO_printf(bio_err, "Error Creating Output File\n");
+			ERR_print_errors(bio_err);	
+			goto end;
+			}
+		}
+	else
+		{
+		out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef OPENSSL_SYS_VMS
+		{
+		    BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+		    out = BIO_push(tmpbio, out);
+		}
+#endif
+	}
+
+	if (sigfile)
+		{
+		BIO *sigbio = BIO_new_file(sigfile, "rb");
+		if (!sigbio)
+			{
+			BIO_printf(bio_err, "Can't open signature file %s\n",
+								sigfile);
+			goto end;
+			}
+		siglen = bio_to_mem(&sig, keysize * 10, sigbio);
+		BIO_free(sigbio);
+		if (siglen <= 0)
+			{
+			BIO_printf(bio_err, "Error reading signature data\n");
+			goto end;
+			}
+		}
+	
+	if (in)
+		{
+		/* Read the input data */
+		buf_inlen = bio_to_mem(&buf_in, keysize * 10, in);
+		if(buf_inlen <= 0)
+			{
+			BIO_printf(bio_err, "Error reading input Data\n");
+			exit(1);
+			}
+		if(rev)
+			{
+			size_t i;
+			unsigned char ctmp;
+			size_t l = (size_t)buf_inlen;
+			for(i = 0; i < l/2; i++)
+				{
+				ctmp = buf_in[i];
+				buf_in[i] = buf_in[l - 1 - i];
+				buf_in[l - 1 - i] = ctmp;
+				}
+			}
+		}
+
+	if(pkey_op == EVP_PKEY_OP_VERIFY)
+		{
+		rv  = EVP_PKEY_verify(ctx, sig, (size_t)siglen,
+				      buf_in, (size_t)buf_inlen);
+		if (rv == 0)
+			BIO_puts(out, "Signature Verification Failure\n");
+		else if (rv == 1)
+			BIO_puts(out, "Signature Verified Successfully\n");
+		if (rv >= 0)
+			goto end;
+		}
+	else
+		{	
+		rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen,
+			      buf_in, (size_t)buf_inlen);
+		if (rv > 0)
+			{
+			buf_out = OPENSSL_malloc(buf_outlen);
+			if (!buf_out)
+				rv = -1;
+			else
+				rv = do_keyop(ctx, pkey_op,
+						buf_out, (size_t *)&buf_outlen,
+						buf_in, (size_t)buf_inlen);
+			}
+		}
+
+	if(rv <= 0)
+		{
+		BIO_printf(bio_err, "Public Key operation error\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+	ret = 0;
+	if(asn1parse)
+		{
+		if(!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1))
+			ERR_print_errors(bio_err);
+		}
+	else if(hexdump)
+		BIO_dump(out, (char *)buf_out, buf_outlen);
+	else
+		BIO_write(out, buf_out, buf_outlen);
+
+	end:
+	if (ctx)
+		EVP_PKEY_CTX_free(ctx);
+	BIO_free(in);
+	BIO_free_all(out);
+	if (buf_in)
+		OPENSSL_free(buf_in);
+	if (buf_out)
+		OPENSSL_free(buf_out);
+	if (sig)
+		OPENSSL_free(sig);
+	return ret;
+}
+
+static void usage()
+{
+	BIO_printf(bio_err, "Usage: pkeyutl [options]\n");
+	BIO_printf(bio_err, "-in file        input file\n");
+	BIO_printf(bio_err, "-out file       output file\n");
+	BIO_printf(bio_err, "-signature file signature file (verify operation only)\n");
+	BIO_printf(bio_err, "-inkey file     input key\n");
+	BIO_printf(bio_err, "-keyform arg    private key format - default PEM\n");
+	BIO_printf(bio_err, "-pubin          input is a public key\n");
+	BIO_printf(bio_err, "-certin         input is a certificate carrying a public key\n");
+	BIO_printf(bio_err, "-pkeyopt X:Y    public key options\n");
+	BIO_printf(bio_err, "-sign           sign with private key\n");
+	BIO_printf(bio_err, "-verify         verify with public key\n");
+	BIO_printf(bio_err, "-verifyrecover  verify with public key, recover original data\n");
+	BIO_printf(bio_err, "-encrypt        encrypt with public key\n");
+	BIO_printf(bio_err, "-decrypt        decrypt with private key\n");
+	BIO_printf(bio_err, "-derive         derive shared secret\n");
+	BIO_printf(bio_err, "-hexdump        hex dump output\n");
+#ifndef OPENSSL_NO_ENGINE
+	BIO_printf(bio_err, "-engine e       use engine e, possibly a hardware device.\n");
+#endif
+	BIO_printf(bio_err, "-passin arg     pass phrase source\n");
+
+}
+
+static EVP_PKEY_CTX *init_ctx(int *pkeysize,
+				char *keyfile, int keyform, int key_type,
+				char *passargin, int pkey_op, ENGINE *e)
+	{
+	EVP_PKEY *pkey = NULL;
+	EVP_PKEY_CTX *ctx = NULL;
+	char *passin = NULL;
+	int rv = -1;
+	X509 *x;
+	if(((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT) 
+		|| (pkey_op == EVP_PKEY_OP_DERIVE))
+		&& (key_type != KEY_PRIVKEY))
+		{
+		BIO_printf(bio_err, "A private key is needed for this operation\n");
+		goto end;
+		}
+	if(!app_passwd(bio_err, passargin, NULL, &passin, NULL))
+		{
+		BIO_printf(bio_err, "Error getting password\n");
+		goto end;
+		}
+	switch(key_type)
+		{
+		case KEY_PRIVKEY:
+		pkey = load_key(bio_err, keyfile, keyform, 0,
+			passin, e, "Private Key");
+		break;
+
+		case KEY_PUBKEY:
+		pkey = load_pubkey(bio_err, keyfile, keyform, 0,
+			NULL, e, "Public Key");
+		break;
+
+		case KEY_CERT:
+		x = load_cert(bio_err, keyfile, keyform,
+			NULL, e, "Certificate");
+		if(x)
+			{
+			pkey = X509_get_pubkey(x);
+			X509_free(x);
+			}
+		break;
+
+		}
+
+	*pkeysize = EVP_PKEY_size(pkey);
+
+	if (!pkey)
+		goto end;
+
+	ctx = EVP_PKEY_CTX_new(pkey, e);
+
+	EVP_PKEY_free(pkey);
+
+	if (!ctx)
+		goto end;
+
+	switch(pkey_op)
+		{
+		case EVP_PKEY_OP_SIGN:
+		rv = EVP_PKEY_sign_init(ctx);
+		break;
+
+		case EVP_PKEY_OP_VERIFY:
+		rv = EVP_PKEY_verify_init(ctx);
+		break;
+
+		case EVP_PKEY_OP_VERIFYRECOVER:
+		rv = EVP_PKEY_verify_recover_init(ctx);
+		break;
+
+		case EVP_PKEY_OP_ENCRYPT:
+		rv = EVP_PKEY_encrypt_init(ctx);
+		break;
+
+		case EVP_PKEY_OP_DECRYPT:
+		rv = EVP_PKEY_decrypt_init(ctx);
+		break;
+
+		case EVP_PKEY_OP_DERIVE:
+		rv = EVP_PKEY_derive_init(ctx);
+		break;
+		}
+
+	if (rv <= 0)
+		{
+		EVP_PKEY_CTX_free(ctx);
+		ctx = NULL;
+		}
+
+	end:
+
+	if (passin)
+		OPENSSL_free(passin);
+
+	return ctx;
+
+
+	}
+
+static int setup_peer(BIO *err, EVP_PKEY_CTX *ctx, int peerform,
+							const char *file)
+	{
+	EVP_PKEY *peer = NULL;
+	int ret;
+	if (!ctx)
+		{
+		BIO_puts(err, "-peerkey command before -inkey\n");
+		return 0;
+		}
+		
+	peer = load_pubkey(bio_err, file, peerform, 0, NULL, NULL, "Peer Key");
+
+	if (!peer)
+		{
+		BIO_printf(bio_err, "Error reading peer key %s\n", file);
+		ERR_print_errors(err);
+		return 0;
+		}
+
+	ret = EVP_PKEY_derive_set_peer(ctx, peer);
+
+	EVP_PKEY_free(peer);
+	if (ret <= 0)
+		ERR_print_errors(err);
+	return ret;
+	}
+
+static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
+		unsigned char *out, size_t *poutlen,
+		unsigned char *in, size_t inlen)
+	{
+	int rv = 0;
+	switch(pkey_op)
+		{
+		case EVP_PKEY_OP_VERIFYRECOVER:
+		rv  = EVP_PKEY_verify_recover(ctx, out, poutlen, in, inlen);
+		break;
+
+		case EVP_PKEY_OP_SIGN:
+		rv  = EVP_PKEY_sign(ctx, out, poutlen, in, inlen);
+		break;
+
+		case EVP_PKEY_OP_ENCRYPT:
+		rv  = EVP_PKEY_encrypt(ctx, out, poutlen, in, inlen);
+		break;
+
+		case EVP_PKEY_OP_DECRYPT:
+		rv  = EVP_PKEY_decrypt(ctx, out, poutlen, in, inlen);
+		break; 
+
+		case EVP_PKEY_OP_DERIVE:
+		rv  = EVP_PKEY_derive(ctx, out, poutlen);
+		break;
+
+		}
+	return rv;
+	}
diff --git a/apps/progs.h b/apps/progs.h
index 6b07c4b..4e7d32a 100644
--- a/apps/progs.h
+++ b/apps/progs.h
@@ -41,7 +41,9 @@
 extern int smime_main(int argc,char *argv[]);
 extern int rand_main(int argc,char *argv[]);
 extern int engine_main(int argc,char *argv[]);
+#ifndef OPENSSL_NO_OCSP
 extern int ocsp_main(int argc,char *argv[]);
+#endif
 extern int prime_main(int argc,char *argv[]);
 
 #define FUNC_TYPE_GENERAL	1
diff --git a/apps/rand.c b/apps/rand.c
index c3b26c4..44a1d46 100644
--- a/apps/rand.c
+++ b/apps/rand.c
@@ -68,7 +68,8 @@
 
 /* -out file         - write to file
  * -rand file:file   - PRNG seed files
- * -base64           - encode output
+ * -base64           - base64 encode output
+ * -hex              - hex encode output
  * num               - write 'num' bytes
  */
 
@@ -84,6 +85,7 @@
 	char *outfile = NULL;
 	char *inrand = NULL;
 	int base64 = 0;
+	int hex = 0;
 	BIO *out = NULL;
 	int num = -1;
 #ifndef OPENSSL_NO_ENGINE
@@ -133,6 +135,13 @@
 			else
 				badopt = 1;
 			}
+		else if (strcmp(argv[i], "-hex") == 0)
+			{
+			if (!hex)
+				hex = 1;
+			else
+				badopt = 1;
+			}
 		else if (isdigit((unsigned char)argv[i][0]))
 			{
 			if (num < 0)
@@ -148,6 +157,9 @@
 			badopt = 1;
 		}
 
+	if (hex && base64)
+		badopt = 1;
+
 	if (num < 0)
 		badopt = 1;
 	
@@ -160,7 +172,8 @@
 		BIO_printf(bio_err, "-engine e             - use engine e, possibly a hardware device.\n");
 #endif
 		BIO_printf(bio_err, "-rand file%cfile%c... - seed PRNG from files\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
-		BIO_printf(bio_err, "-base64               - encode output\n");
+		BIO_printf(bio_err, "-base64               - base64 encode output\n");
+		BIO_printf(bio_err, "-hex                  - hex encode output\n");
 		goto err;
 		}
 
@@ -210,9 +223,17 @@
 		r = RAND_bytes(buf, chunk);
 		if (r <= 0)
 			goto err;
-		BIO_write(out, buf, chunk);
+		if (!hex) 
+			BIO_write(out, buf, chunk);
+		else
+			{
+			for (i = 0; i < chunk; i++)
+				BIO_printf(out, "%02x", buf[i]);
+			}
 		num -= chunk;
 		}
+	if (hex)
+		BIO_puts(out, "\n");
 	(void)BIO_flush(out);
 
 	app_RAND_write_file(NULL, bio_err);
diff --git a/apps/rsautl.c b/apps/rsautl.c
index f3c458e..923e2b6 100644
--- a/apps/rsautl.c
+++ b/apps/rsautl.c
@@ -1,5 +1,5 @@
 /* rsautl.c */
-/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/apps/s_client.c b/apps/s_client.c
index 4ab3cba..4974f5f 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -221,6 +221,7 @@
 	BIO_printf(bio_err," -crlf         - convert LF from terminal into CRLF\n");
 	BIO_printf(bio_err," -quiet        - no s_client output\n");
 	BIO_printf(bio_err," -ign_eof      - ignore input eof (default when -quiet)\n");
+	BIO_printf(bio_err," -no_ign_eof   - don't ignore input eof\n");
 	BIO_printf(bio_err," -ssl2         - just use SSLv2\n");
 	BIO_printf(bio_err," -ssl3         - just use SSLv3\n");
 	BIO_printf(bio_err," -tls1         - just use TLSv1\n");
@@ -234,7 +235,8 @@
 	BIO_printf(bio_err," -starttls prot - use the STARTTLS command before starting TLS\n");
 	BIO_printf(bio_err,"                 for those protocols that support it, where\n");
 	BIO_printf(bio_err,"                 'prot' defines which one to assume.  Currently,\n");
-	BIO_printf(bio_err,"                 only \"smtp\", \"pop3\", \"imap\", and \"ftp\" are supported.\n");
+	BIO_printf(bio_err,"                 only \"smtp\", \"pop3\", \"imap\", \"ftp\" and \"xmpp\"\n");
+	BIO_printf(bio_err,"                 are supported.\n");
 #ifndef OPENSSL_NO_ENGINE
 	BIO_printf(bio_err," -engine id    - Initialise and use the specified engine\n");
 #endif
@@ -276,7 +278,8 @@
 	PROTO_SMTP,
 	PROTO_POP3,
 	PROTO_IMAP,
-	PROTO_FTP
+	PROTO_FTP,
+	PROTO_XMPP
 };
 
 int MAIN(int, char **);
@@ -315,7 +318,11 @@
 	BIO *sbio;
 	char *inrand=NULL;
 	int mbuf_len=0;
+#ifndef OPENSSL_NO_ENGINE
 	char *engine_id=NULL;
+	char *ssl_client_engine_id=NULL;
+	ENGINE *ssl_client_engine=NULL;
+#endif
 	ENGINE *e=NULL;
 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
 	struct timeval tv;
@@ -332,6 +339,9 @@
 	int peerlen = sizeof(peer);
 	int enable_timeouts = 0 ;
 	long mtu = 0;
+#ifndef OPENSSL_NO_JPAKE
+	char *jpake_secret = NULL;
+#endif
 
 #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
 	meth=SSLv23_client_method();
@@ -432,6 +442,8 @@
 			}
 		else if	(strcmp(*argv,"-ign_eof") == 0)
 			c_ign_eof=1;
+		else if	(strcmp(*argv,"-no_ign_eof") == 0)
+			c_ign_eof=0;
 		else if	(strcmp(*argv,"-pause") == 0)
 			c_Pause=1;
 		else if	(strcmp(*argv,"-debug") == 0)
@@ -544,6 +556,8 @@
 				starttls_proto = PROTO_IMAP;
 			else if (strcmp(*argv,"ftp") == 0)
 				starttls_proto = PROTO_FTP;
+			else if (strcmp(*argv, "xmpp") == 0)
+				starttls_proto = PROTO_XMPP;
 			else
 				goto bad;
 			}
@@ -553,6 +567,11 @@
 			if (--argc < 1) goto bad;
 			engine_id = *(++argv);
 			}
+		else if	(strcmp(*argv,"-ssl_client_engine") == 0)
+			{
+			if (--argc < 1) goto bad;
+			ssl_client_engine_id = *(++argv);
+			}
 #endif
 		else if (strcmp(*argv,"-rand") == 0)
 			{
@@ -567,6 +586,13 @@
 			/* meth=TLSv1_client_method(); */
 			}
 #endif
+#ifndef OPENSSL_NO_JPAKE
+		else if (strcmp(*argv,"-jpake") == 0)
+			{
+			if (--argc < 1) goto bad;
+			jpake_secret = *++argv;
+			}
+#endif
 		else
 			{
 			BIO_printf(bio_err,"unknown option %s\n",*argv);
@@ -588,6 +614,16 @@
 
 #ifndef OPENSSL_NO_ENGINE
         e = setup_engine(bio_err, engine_id, 1);
+	if (ssl_client_engine_id)
+		{
+		ssl_client_engine = ENGINE_by_id(ssl_client_engine_id);
+		if (!ssl_client_engine)
+			{
+			BIO_printf(bio_err,
+					"Error getting client auth engine\n");
+			goto end;
+			}
+		}
 #endif
 	if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
 		{
@@ -655,6 +691,20 @@
 		goto end;
 		}
 
+#ifndef OPENSSL_NO_ENGINE
+	if (ssl_client_engine)
+		{
+		if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine))
+			{
+			BIO_puts(bio_err, "Error setting client auth engine\n");
+			ERR_print_errors(bio_err);
+			ENGINE_free(ssl_client_engine);
+			goto end;
+			}
+		ENGINE_free(ssl_client_engine);
+		}
+#endif
+
 	if (bugs)
 		SSL_CTX_set_options(ctx,SSL_OP_ALL|off);
 	else
@@ -805,8 +855,6 @@
 	else
 		sbio=BIO_new_socket(s,BIO_NOCLOSE);
 
-
-
 	if (nbio_test)
 		{
 		BIO *test;
@@ -850,6 +898,10 @@
 #endif
 		}
 #endif
+#ifndef OPENSSL_NO_JPAKE
+	if (jpake_secret)
+		jpake_client_auth(bio_c_out, sbio, jpake_secret);
+#endif
 
 	SSL_set_bio(con,sbio,sbio);
 	SSL_set_connect_state(con);
@@ -956,6 +1008,28 @@
 		BIO_printf(sbio,"AUTH TLS\r\n");
 		BIO_read(sbio,sbuf,BUFSIZZ);
 		}
+	if (starttls_proto == PROTO_XMPP)
+		{
+		int seen = 0;
+		BIO_printf(sbio,"<stream:stream "
+		    "xmlns:stream='http://etherx.jabber.org/streams' "
+		    "xmlns='jabber:client' to='%s' version='1.0'>", host);
+		seen = BIO_read(sbio,mbuf,BUFSIZZ);
+		mbuf[seen] = 0;
+		while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'"))
+			{
+			if (strstr(mbuf, "/stream:features>"))
+				goto shut;
+			seen = BIO_read(sbio,mbuf,BUFSIZZ);
+			mbuf[seen] = 0;
+			}
+		BIO_printf(sbio, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
+		seen = BIO_read(sbio,sbuf,BUFSIZZ);
+		sbuf[seen] = 0;
+		if (!strstr(sbuf, "<proceed"))
+			goto shut;
+		mbuf[0] = 0;
+		}
 
 	for (;;)
 		{
diff --git a/apps/s_server.c b/apps/s_server.c
index 7919c43..84b1b28 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -742,6 +742,10 @@
 #endif
 int MAIN(int, char **);
 
+#ifndef OPENSSL_NO_JPAKE
+static char *jpake_secret = NULL;
+#endif
+
 int MAIN(int argc, char *argv[])
 	{
 	X509_STORE *store = NULL;
@@ -760,9 +764,7 @@
 	int state=0;
 	SSL_METHOD *meth=NULL;
         int socket_type=SOCK_STREAM;
-#ifndef OPENSSL_NO_ENGINE
 	ENGINE *e=NULL;
-#endif
 	char *inrand=NULL;
 	int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
 	char *passarg = NULL, *pass = NULL;
@@ -774,7 +776,6 @@
 	EVP_PKEY *s_key2 = NULL;
 	X509 *s_cert2 = NULL;
 #endif
-
 #ifndef OPENSSL_NO_TLSEXT
         tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING};
 #endif
@@ -1071,6 +1072,14 @@
 			if (--argc < 1) goto bad;
 			s_key_file2= *(++argv);
 			}
+			
+#endif
+#ifndef OPENSSL_NO_JPAKE
+		else if (strcmp(*argv,"-jpake") == 0)
+			{
+			if (--argc < 1) goto bad;
+			jpake_secret = *(++argv);
+			}
 #endif
 		else
 			{
@@ -1673,6 +1682,11 @@
 		test=BIO_new(BIO_f_nbio_test());
 		sbio=BIO_push(test,sbio);
 		}
+#ifndef OPENSSL_NO_JPAKE
+	if(jpake_secret)
+		jpake_server_auth(bio_s_out, sbio, jpake_secret);
+#endif
+
 	SSL_set_bio(con,sbio,sbio);
 	SSL_set_accept_state(con);
 	/* SSL_set_fd(con,s); */
diff --git a/apps/smime.c b/apps/smime.c
index ce8a1cb..75804b8 100644
--- a/apps/smime.c
+++ b/apps/smime.c
@@ -1,5 +1,5 @@
 /* smime.c */
-/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
  * project.
  */
 /* ====================================================================
diff --git a/apps/speed.c b/apps/speed.c
index 65b8483..6b135fb 100644
--- a/apps/speed.c
+++ b/apps/speed.c
@@ -2762,6 +2762,8 @@
 	for(n=0 ; n < multi ; ++n)
 		{
 		pipe(fd);
+		fflush(stdout);
+		fflush(stderr);
 		if(fork())
 			{
 			close(fd[1]);
diff --git a/apps/spkac.c b/apps/spkac.c
index 01fe406..0e01ea9 100644
--- a/apps/spkac.c
+++ b/apps/spkac.c
@@ -1,6 +1,6 @@
 /* apps/spkac.c */
 
-/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
  * project 1999. Based on an original idea by Massimiliano Pala
  * ([email protected]).
  */
diff --git a/apps/ts.c b/apps/ts.c
new file mode 100644
index 0000000..74e7e93
--- /dev/null
+++ b/apps/ts.c
@@ -0,0 +1,1144 @@
+/* apps/ts.c */
+/* Written by Zoltan Glozik ([email protected]) for the OpenSSL
+ * project 2002.
+ */
+/* ====================================================================
+ * Copyright (c) 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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+#include <openssl/ts.h>
+#include <openssl/bn.h>
+
+#undef PROG
+#define PROG	ts_main
+
+/* Length of the nonce of the request in bits (must be a multiple of 8). */
+#define	NONCE_LENGTH		64
+
+/* Macro definitions for the configuration file. */
+#define	ENV_OID_FILE		"oid_file"
+
+/* Local function declarations. */
+
+static ASN1_OBJECT *txt2obj(const char *oid);
+static CONF *load_config_file(const char *configfile);
+
+/* Query related functions. */
+static int query_command(const char *data, char *digest,
+			 const EVP_MD *md, const char *policy, int no_nonce, 
+			 int cert, const char *in, const char *out, int text);
+static BIO *BIO_open_with_default(const char *file, const char *mode, 
+				  FILE *default_fp);
+static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md,
+			    const char *policy, int no_nonce, int cert);
+static int create_digest(BIO *input, char *digest,
+			 const EVP_MD *md, unsigned char **md_value);
+static ASN1_INTEGER *create_nonce(int bits);
+
+/* Reply related functions. */
+static int reply_command(CONF *conf, char *section, char *engine, 
+			 char *queryfile, char *passin, char *inkey, 
+			 char *signer, char *chain, const char *policy, 
+			 char *in, int token_in, char *out, int token_out,
+			 int text);
+static TS_RESP *read_PKCS7(BIO *in_bio);
+static TS_RESP *create_response(CONF *conf, const char *section, char *engine,
+				char *queryfile, char *passin, char *inkey,
+				char *signer, char *chain, const char *policy);
+static ASN1_INTEGER * MS_CALLBACK serial_cb(TS_RESP_CTX *ctx, void *data);
+static ASN1_INTEGER *next_serial(const char *serialfile);
+static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial);
+
+/* Verify related functions. */
+static int verify_command(char *data, char *digest, char *queryfile,
+			  char *in, int token_in,
+			  char *ca_path, char *ca_file, char *untrusted);
+static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest, 
+					char *queryfile, 
+					char *ca_path, char *ca_file,
+					char *untrusted);
+static X509_STORE *create_cert_store(char *ca_path, char *ca_file);
+static int MS_CALLBACK verify_cb(int ok, X509_STORE_CTX *ctx);
+
+/* Main function definition. */
+int MAIN(int, char **);
+
+int MAIN(int argc, char **argv)
+	{
+	int ret = 1;
+	char *configfile = NULL;
+	char *section = NULL;
+	CONF *conf = NULL;
+	enum mode {
+	CMD_NONE, CMD_QUERY, CMD_REPLY, CMD_VERIFY 
+	} mode = CMD_NONE;
+	char *data = NULL;
+	char *digest = NULL;
+	const EVP_MD *md = NULL;
+	char *rnd = NULL;
+	char *policy = NULL;
+	int no_nonce = 0;
+	int cert = 0;
+	char *in = NULL;
+	char *out = NULL;
+	int text = 0;
+	char *queryfile = NULL;
+	char *passin = NULL;	/* Password source. */
+	char *password =NULL;	/* Password itself. */
+	char *inkey = NULL;
+	char *signer = NULL;
+	char *chain = NULL;
+	char *ca_path = NULL;
+	char *ca_file = NULL;
+	char *untrusted = NULL;
+	char *engine = NULL;
+	/* Input is ContentInfo instead of TimeStampResp. */
+	int token_in = 0;	
+	/* Output is ContentInfo instead of TimeStampResp. */
+	int token_out = 0;
+	int free_bio_err = 0;
+
+	ERR_load_crypto_strings();
+	apps_startup();
+
+	if (bio_err == NULL && (bio_err = BIO_new(BIO_s_file())) != NULL)
+		{
+		free_bio_err = 1;
+		BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
+		}
+
+	for (argc--, argv++; argc > 0; argc--, argv++)
+		{
+		if (strcmp(*argv, "-config") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			configfile = *++argv;
+			}
+		else if (strcmp(*argv, "-section") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			section = *++argv;
+			}
+		else if (strcmp(*argv, "-query") == 0)
+			{
+			if (mode != CMD_NONE) goto usage;
+			mode = CMD_QUERY;
+			}
+		else if (strcmp(*argv, "-data") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			data = *++argv;
+			}
+		else if (strcmp(*argv, "-digest") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			digest = *++argv;
+			}
+		else if (strcmp(*argv, "-rand") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			rnd = *++argv;
+			}
+		else if (strcmp(*argv, "-policy") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			policy = *++argv;
+			}
+		else if (strcmp(*argv, "-no_nonce") == 0)
+			{
+			no_nonce = 1;
+			}
+		else if (strcmp(*argv, "-cert") == 0)
+			{
+			cert = 1;
+			}
+		else if (strcmp(*argv, "-in") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			in = *++argv;
+			}
+		else if (strcmp(*argv, "-token_in") == 0)
+			{
+			token_in = 1;
+			}
+		else if (strcmp(*argv, "-out") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			out = *++argv;
+			}
+		else if (strcmp(*argv, "-token_out") == 0)
+			{
+			token_out = 1;
+			}
+		else if (strcmp(*argv, "-text") == 0)
+			{
+			text = 1;
+			}
+		else if (strcmp(*argv, "-reply") == 0)
+			{
+			if (mode != CMD_NONE) goto usage;
+			mode = CMD_REPLY;
+			}
+		else if (strcmp(*argv, "-queryfile") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			queryfile = *++argv;
+			}
+		else if (strcmp(*argv, "-passin") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			passin = *++argv;
+			}
+		else if (strcmp(*argv, "-inkey") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			inkey = *++argv;
+			}
+		else if (strcmp(*argv, "-signer") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			signer = *++argv;
+			}
+		else if (strcmp(*argv, "-chain") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			chain = *++argv;
+			}
+		else if (strcmp(*argv, "-verify") == 0)
+			{
+			if (mode != CMD_NONE) goto usage;
+			mode = CMD_VERIFY;
+			}
+		else if (strcmp(*argv, "-CApath") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			ca_path = *++argv;
+			}
+		else if (strcmp(*argv, "-CAfile") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			ca_file = *++argv;
+			}
+		else if (strcmp(*argv, "-untrusted") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			untrusted = *++argv;
+			}
+		else if (strcmp(*argv, "-engine") == 0)
+			{
+			if (argc-- < 1) goto usage;
+			engine = *++argv;
+			}
+		else if ((md = EVP_get_digestbyname(*argv + 1)) != NULL)
+			{
+			/* empty. */
+			}
+		else
+			goto usage;
+		}
+	
+	/* Seed the random number generator if it is going to be used. */
+	if (mode == CMD_QUERY && !no_nonce)
+		{
+		if (!app_RAND_load_file(NULL, bio_err, 1) && rnd == NULL)
+			BIO_printf(bio_err, "warning, not much extra random "
+				   "data, consider using the -rand option\n");
+		if (rnd != NULL)
+			BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
+				   app_RAND_load_files(rnd));
+		}
+
+	/* Get the password if required. */
+	if(mode == CMD_REPLY && passin &&
+	   !app_passwd(bio_err, passin, NULL, &password, NULL))
+		{
+		BIO_printf(bio_err,"Error getting password.\n");
+		goto cleanup;
+		}
+
+	/* Check consistency of parameters and execute 
+	   the appropriate function. */
+	switch (mode)
+		{
+	case CMD_NONE:
+		goto usage;
+	case CMD_QUERY:
+		/* Data file and message imprint cannot be specified
+		   at the same time. */
+		ret = data != NULL && digest != NULL;
+		if (ret) goto usage;
+		/* Load the config file for possible policy OIDs. */
+		conf = load_config_file(configfile);
+		ret = !query_command(data, digest, md, policy, no_nonce, cert,
+				     in, out, text);
+		break;
+	case CMD_REPLY:
+		conf = load_config_file(configfile);
+		if (in == NULL)
+			{
+			ret = !(queryfile != NULL && conf != NULL && !token_in);
+			if (ret) goto usage;
+			}
+		else
+			{
+			/* 'in' and 'queryfile' are exclusive. */
+			ret = !(queryfile == NULL);
+			if (ret) goto usage;
+			}
+
+		ret = !reply_command(conf, section, engine, queryfile, 
+				     password, inkey, signer, chain, policy, 
+				     in, token_in, out, token_out, text);
+		break;
+	case CMD_VERIFY:
+		ret = !(((queryfile && !data && !digest)
+			 || (!queryfile && data && !digest)
+			 || (!queryfile && !data && digest))
+			&& in != NULL);
+		if (ret) goto usage;
+
+		ret = !verify_command(data, digest, queryfile, in, token_in,
+				      ca_path, ca_file, untrusted);
+		}
+
+	goto cleanup;
+
+ usage:
+	BIO_printf(bio_err, "usage:\n"
+		   "ts -query [-rand file%cfile%c...] [-config configfile] "
+		   "[-data file_to_hash] [-digest digest_bytes]"
+		   "[-md2|-md4|-md5|-sha|-sha1|-mdc2|-ripemd160] "
+		   "[-policy object_id] [-no_nonce] [-cert] "
+		   "[-in request.tsq] [-out request.tsq] [-text]\n",
+		   LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
+	BIO_printf(bio_err, "or\n"
+		   "ts -reply [-config configfile] [-section tsa_section] "
+		   "[-queryfile request.tsq] [-passin password] "
+		   "[-signer tsa_cert.pem] [-inkey private_key.pem] "
+		   "[-chain certs_file.pem] [-policy object_id] "
+		   "[-in response.tsr] [-token_in] "
+		   "[-out response.tsr] [-token_out] [-text] [-engine id]\n");
+	BIO_printf(bio_err, "or\n"
+		   "ts -verify [-data file_to_hash] [-digest digest_bytes] "
+		   "[-queryfile request.tsq] "
+		   "-in response.tsr [-token_in] "
+		   "-CApath ca_path -CAfile ca_file.pem "
+		   "-untrusted cert_file.pem\n");
+ cleanup:
+	/* Clean up. */
+	app_RAND_write_file(NULL, bio_err);
+	NCONF_free(conf);
+	OPENSSL_free(password);
+	OBJ_cleanup();
+	if (free_bio_err)
+		{
+		BIO_free_all(bio_err);
+		bio_err = NULL;
+		}
+
+	OPENSSL_EXIT(ret);
+	}
+
+/*
+ * Configuration file-related function definitions.
+ */
+
+static ASN1_OBJECT *txt2obj(const char *oid)
+	{
+	ASN1_OBJECT *oid_obj = NULL;
+
+	if (!(oid_obj = OBJ_txt2obj(oid, 0)))
+		BIO_printf(bio_err, "cannot convert %s to OID\n", oid);
+
+	return oid_obj;
+	}
+
+static CONF *load_config_file(const char *configfile)
+	{
+	CONF *conf = NULL;
+	long errorline = -1;
+
+	if (!configfile) configfile = getenv("OPENSSL_CONF");
+	if (!configfile) configfile = getenv("SSLEAY_CONF");
+
+	if (configfile &&
+	    (!(conf = NCONF_new(NULL)) ||
+	     NCONF_load(conf, configfile, &errorline) <= 0))
+		{
+		if (errorline <= 0)
+			BIO_printf(bio_err, "error loading the config file "
+				   "'%s'\n", configfile);
+		else
+			BIO_printf(bio_err, "error on line %ld of config file "
+				   "'%s'\n", errorline, configfile);
+		}
+
+	if (conf != NULL)
+		{
+		const char *p;
+
+		BIO_printf(bio_err,"Using configuration from %s\n", configfile);
+		p = NCONF_get_string(conf, NULL, ENV_OID_FILE);
+		if (p != NULL)
+			{
+			BIO *oid_bio = BIO_new_file(p, "r");
+			if (!oid_bio) 
+				ERR_print_errors(bio_err);
+			else
+				{
+				OBJ_create_objects(oid_bio);
+				BIO_free_all(oid_bio);
+				}
+			}
+		else
+			ERR_clear_error();
+		if(!add_oid_section(bio_err, conf)) 
+			ERR_print_errors(bio_err);
+		}
+	return conf;
+	}
+
+/*
+ * Query-related method definitions.
+ */
+
+static int query_command(const char *data, char *digest, const EVP_MD *md,
+			 const char *policy, int no_nonce, 
+			 int cert, const char *in, const char *out, int text)
+	{
+	int ret = 0;
+	TS_REQ *query = NULL;
+	BIO *in_bio = NULL;
+	BIO *data_bio = NULL;
+	BIO *out_bio = NULL;
+
+	/* Build query object either from file or from scratch. */
+	if (in != NULL)
+		{
+		if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end;
+		query = d2i_TS_REQ_bio(in_bio, NULL);
+		}
+	else
+		{
+		/* Open the file if no explicit digest bytes were specified. */
+		if (!digest 
+		    && !(data_bio = BIO_open_with_default(data, "rb", stdin)))
+			goto end;
+		/* Creating the query object. */
+		query = create_query(data_bio, digest, md,
+				     policy, no_nonce, cert);
+		/* Saving the random number generator state. */
+		}
+	if (query == NULL) goto end;
+
+	/* Write query either in ASN.1 or in text format. */
+	if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL)
+		goto end;
+	if (text)
+		{
+		/* Text output. */
+		if (!TS_REQ_print_bio(out_bio, query))
+			goto end;
+		}
+	else
+		{
+		/* ASN.1 output. */
+		if (!i2d_TS_REQ_bio(out_bio, query))
+			goto end;
+		}
+
+	ret = 1;
+
+ end:
+	ERR_print_errors(bio_err);
+
+	/* Clean up. */
+	BIO_free_all(in_bio);
+	BIO_free_all(data_bio);
+	BIO_free_all(out_bio);
+	TS_REQ_free(query);
+
+	return ret;
+	}
+
+static BIO *BIO_open_with_default(const char *file, const char *mode, 
+				  FILE *default_fp)
+	{
+	return file == NULL ? 
+		BIO_new_fp(default_fp, BIO_NOCLOSE) 
+		: BIO_new_file(file, mode);
+	}
+
+static TS_REQ *create_query(BIO *data_bio, char *digest, const EVP_MD *md,
+			    const char *policy, int no_nonce, int cert)
+	{
+	int ret = 0;
+	TS_REQ *ts_req = NULL;
+	int len;
+	TS_MSG_IMPRINT *msg_imprint = NULL;
+	X509_ALGOR *algo = NULL;
+	unsigned char *data = NULL;
+	ASN1_OBJECT *policy_obj = NULL;
+	ASN1_INTEGER *nonce_asn1 = NULL;
+
+	/* Setting default message digest. */
+	if (!md && !(md = EVP_get_digestbyname("sha1"))) goto err;
+
+	/* Creating request object. */
+	if (!(ts_req = TS_REQ_new())) goto err;
+
+	/* Setting version. */
+	if (!TS_REQ_set_version(ts_req, 1)) goto err;
+
+	/* Creating and adding MSG_IMPRINT object. */
+	if (!(msg_imprint = TS_MSG_IMPRINT_new())) goto err;
+
+	/* Adding algorithm. */
+	if (!(algo = X509_ALGOR_new())) goto err;
+	if (!(algo->algorithm = OBJ_nid2obj(EVP_MD_type(md)))) goto err;
+	if (!(algo->parameter = ASN1_TYPE_new())) goto err;
+	algo->parameter->type = V_ASN1_NULL;
+	if (!TS_MSG_IMPRINT_set_algo(msg_imprint, algo)) goto err;
+
+	/* Adding message digest. */
+	if ((len = create_digest(data_bio, digest, md, &data)) == 0)
+		goto err;
+	if (!TS_MSG_IMPRINT_set_msg(msg_imprint, data, len)) goto err;
+
+	if (!TS_REQ_set_msg_imprint(ts_req, msg_imprint)) goto err;
+	
+	/* Setting policy if requested. */
+	if (policy && !(policy_obj = txt2obj(policy))) goto err;
+	if (policy_obj && !TS_REQ_set_policy_id(ts_req, policy_obj)) goto err;
+
+	/* Setting nonce if requested. */
+	if (!no_nonce && !(nonce_asn1 = create_nonce(NONCE_LENGTH))) goto err;
+	if (nonce_asn1 && !TS_REQ_set_nonce(ts_req, nonce_asn1)) goto err;
+
+	/* Setting certificate request flag if requested. */
+	if (!TS_REQ_set_cert_req(ts_req, cert)) goto err;
+
+	ret = 1;
+ err:
+	if (!ret)
+		{
+		TS_REQ_free(ts_req);
+		ts_req = NULL;
+		BIO_printf(bio_err, "could not create query\n");
+		}
+	TS_MSG_IMPRINT_free(msg_imprint);
+	X509_ALGOR_free(algo);
+	OPENSSL_free(data);
+	ASN1_OBJECT_free(policy_obj);
+	ASN1_INTEGER_free(nonce_asn1);
+	return ts_req;
+	}
+
+static int create_digest(BIO *input, char *digest, const EVP_MD *md,
+			 unsigned char **md_value)
+	{
+	int md_value_len;
+
+	md_value_len = EVP_MD_size(md);
+	if (md_value_len < 0)
+	    goto err;
+	if (input)
+		{
+		/* Digest must be computed from an input file. */
+		EVP_MD_CTX md_ctx;
+		unsigned char buffer[4096];
+		int length;
+
+		*md_value = OPENSSL_malloc(md_value_len);
+		if (*md_value == 0) goto err;
+
+		EVP_DigestInit(&md_ctx, md);
+		while ((length = BIO_read(input, buffer, sizeof(buffer))) > 0)
+			{
+			EVP_DigestUpdate(&md_ctx, buffer, length);
+			}
+		EVP_DigestFinal(&md_ctx, *md_value, NULL);
+		}
+	else
+		{
+		/* Digest bytes are specified with digest. */
+		long digest_len;
+		*md_value = string_to_hex(digest, &digest_len);
+		if (!*md_value || md_value_len != digest_len)
+			{
+			OPENSSL_free(*md_value);
+			*md_value = NULL;
+			BIO_printf(bio_err, "bad digest, %d bytes "
+				   "must be specified\n", md_value_len);
+			goto err;
+			}
+		}
+
+	return md_value_len;
+ err:
+	return 0;
+	}
+
+static ASN1_INTEGER *create_nonce(int bits)
+	{
+	unsigned char buf[20];
+	ASN1_INTEGER *nonce = NULL;
+	int len = (bits - 1) / 8 + 1;
+	int i;
+
+	/* Generating random byte sequence. */
+	if (len > (int)sizeof(buf)) goto err;
+	if (!RAND_bytes(buf, len)) goto err;
+
+	/* Find the first non-zero byte and creating ASN1_INTEGER object. */
+	for (i = 0; i < len && !buf[i]; ++i);
+	if (!(nonce = ASN1_INTEGER_new())) goto err;
+	OPENSSL_free(nonce->data);
+	/* Allocate at least one byte. */
+	nonce->length = len - i;
+	if (!(nonce->data = OPENSSL_malloc(nonce->length + 1))) goto err;
+	memcpy(nonce->data, buf + i, nonce->length);
+
+	return nonce;
+ err:
+	BIO_printf(bio_err, "could not create nonce\n");
+	ASN1_INTEGER_free(nonce);
+	return NULL;
+	}
+/*
+ * Reply-related method definitions.
+ */
+
+static int reply_command(CONF *conf, char *section, char *engine, 
+			 char *queryfile, char *passin, char *inkey,
+			 char *signer, char *chain, const char *policy, 
+			 char *in, int token_in,
+			 char *out, int token_out, int text)
+	{
+	int ret = 0;
+	TS_RESP *response = NULL;
+	BIO *in_bio = NULL;
+	BIO *query_bio = NULL;
+	BIO *inkey_bio = NULL;
+	BIO *signer_bio = NULL;
+	BIO *out_bio = NULL;
+
+	/* Build response object either from response or query. */
+	if (in != NULL)
+		{
+		if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end;
+		if (token_in)
+			{
+			/* We have a ContentInfo (PKCS7) object, add
+			   'granted' status info around it. */
+			response = read_PKCS7(in_bio);
+			}
+		else
+			{
+			/* We have a ready-made TS_RESP object. */
+			response = d2i_TS_RESP_bio(in_bio, NULL);
+			}
+		}
+	else
+		{
+		response = create_response(conf, section, engine, queryfile,
+					   passin, inkey, signer, chain,
+					   policy);
+		if (response)
+			BIO_printf(bio_err, "Response has been generated.\n");
+		else
+			BIO_printf(bio_err, "Response is not generated.\n");
+		}
+	if (response == NULL) goto end;
+
+	/* Write response either in ASN.1 or text format. */
+	if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL)
+		goto end;
+	if (text)
+		{
+		/* Text output. */
+		if (token_out)
+			{
+			TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response);
+			if (!TS_TST_INFO_print_bio(out_bio, tst_info)) goto end;
+			}
+		else
+			{
+			if (!TS_RESP_print_bio(out_bio, response)) goto end;
+			}
+		}
+	else
+		{
+		/* ASN.1 DER output. */
+		if (token_out)
+			{
+			PKCS7 *token = TS_RESP_get_token(response);
+			if (!i2d_PKCS7_bio(out_bio, token)) goto end;
+			}
+		else
+			{
+			if (!i2d_TS_RESP_bio(out_bio, response)) goto end;
+			}
+		}
+
+	ret = 1;
+
+ end:
+	ERR_print_errors(bio_err);
+
+	/* Clean up. */
+	BIO_free_all(in_bio);
+	BIO_free_all(query_bio);
+	BIO_free_all(inkey_bio);
+	BIO_free_all(signer_bio);
+	BIO_free_all(out_bio);
+	TS_RESP_free(response);
+
+	return ret;
+	}
+
+/* Reads a PKCS7 token and adds default 'granted' status info to it. */
+static TS_RESP *read_PKCS7(BIO *in_bio)
+	{
+	int ret = 0;
+	PKCS7 *token = NULL;
+	TS_TST_INFO *tst_info = NULL;
+	TS_RESP *resp = NULL;
+	TS_STATUS_INFO *si = NULL;
+
+	/* Read PKCS7 object and extract the signed time stamp info. */
+	if (!(token = d2i_PKCS7_bio(in_bio, NULL))) goto end;
+	if (!(tst_info = PKCS7_to_TS_TST_INFO(token))) goto end;
+
+	/* Creating response object. */
+	if (!(resp = TS_RESP_new())) goto end;
+
+	/* Create granted status info. */
+	if (!(si = TS_STATUS_INFO_new())) goto end;
+	if (!(ASN1_INTEGER_set(si->status, TS_STATUS_GRANTED))) goto end;
+	if (!TS_RESP_set_status_info(resp, si)) goto end;
+
+	/* Setting encapsulated token. */
+	TS_RESP_set_tst_info(resp, token, tst_info);
+	token = NULL;		/* Ownership is lost. */
+	tst_info = NULL;	/* Ownership is lost. */
+
+	ret = 1;
+ end:
+	PKCS7_free(token);
+	TS_TST_INFO_free(tst_info);
+	if (!ret)
+		{
+		TS_RESP_free(resp);
+		resp = NULL;
+		}
+	TS_STATUS_INFO_free(si);
+	return resp;
+	}
+
+static TS_RESP *create_response(CONF *conf, const char *section, char *engine, 
+				char *queryfile, char *passin, char *inkey,
+				char *signer, char *chain, const char *policy)
+	{
+	int ret = 0;
+	TS_RESP *response = NULL;
+	BIO *query_bio = NULL;
+	TS_RESP_CTX *resp_ctx = NULL;
+
+	if (!(query_bio = BIO_new_file(queryfile, "rb")))
+		goto end;
+
+	/* Getting TSA configuration section. */
+	if (!(section = TS_CONF_get_tsa_section(conf, section)))
+		goto end;
+
+	/* Setting up response generation context. */
+	if (!(resp_ctx = TS_RESP_CTX_new())) goto end;
+
+	/* Setting serial number provider callback. */
+	if (!TS_CONF_set_serial(conf, section, serial_cb, resp_ctx)) goto end;
+#ifndef OPENSSL_NO_ENGINE
+	/* Setting default OpenSSL engine. */
+	if (!TS_CONF_set_crypto_device(conf, section, engine)) goto end;
+#endif
+
+	/* Setting TSA signer certificate. */
+	if (!TS_CONF_set_signer_cert(conf, section, signer, resp_ctx)) goto end;
+
+	/* Setting TSA signer certificate chain. */
+	if (!TS_CONF_set_certs(conf, section, chain, resp_ctx)) goto end;
+
+	/* Setting TSA signer private key. */
+	if (!TS_CONF_set_signer_key(conf, section, inkey, passin, resp_ctx))
+		goto end;
+
+	/* Setting default policy OID. */
+	if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx)) goto end;
+
+	/* Setting acceptable policy OIDs. */
+	if (!TS_CONF_set_policies(conf, section, resp_ctx)) goto end;
+
+	/* Setting the acceptable one-way hash algorithms. */
+	if (!TS_CONF_set_digests(conf, section, resp_ctx)) goto end;
+
+	/* Setting guaranteed time stamp accuracy. */
+	if (!TS_CONF_set_accuracy(conf, section, resp_ctx)) goto end;
+
+	/* Setting the precision of the time. */
+	if (!TS_CONF_set_clock_precision_digits(conf, section, resp_ctx))
+		goto end;
+
+	/* Setting the ordering flaf if requested. */
+	if (!TS_CONF_set_ordering(conf, section, resp_ctx)) goto end;
+
+	/* Setting the TSA name required flag if requested. */
+	if (!TS_CONF_set_tsa_name(conf, section, resp_ctx)) goto end;
+
+	/* Setting the ESS cert id chain flag if requested. */
+	if (!TS_CONF_set_ess_cert_id_chain(conf, section, resp_ctx)) goto end;
+
+	/* Creating the response. */
+	if (!(response = TS_RESP_create_response(resp_ctx, query_bio)))
+		goto end;
+
+	ret = 1;
+ end:
+	if (!ret) 
+		{
+		TS_RESP_free(response);
+		response = NULL;
+		}
+	TS_RESP_CTX_free(resp_ctx);
+	BIO_free_all(query_bio);
+
+	return response;
+	}
+
+static ASN1_INTEGER * MS_CALLBACK serial_cb(TS_RESP_CTX *ctx, void *data)
+	{
+	const char *serial_file = (const char *) data;
+	ASN1_INTEGER *serial = next_serial(serial_file);
+
+	if (!serial)
+		{
+		TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
+					    "Error during serial number "
+					    "generation.");
+		TS_RESP_CTX_add_failure_info(ctx,
+					     TS_INFO_ADD_INFO_NOT_AVAILABLE);
+		}
+	else
+		save_ts_serial(serial_file, serial);
+
+	return serial;
+	}
+
+static ASN1_INTEGER *next_serial(const char *serialfile)
+	{
+	int ret = 0;
+	BIO *in = NULL;
+	ASN1_INTEGER *serial = NULL;
+	BIGNUM *bn = NULL;
+
+	if (!(serial = ASN1_INTEGER_new())) goto err;
+
+	if (!(in = BIO_new_file(serialfile, "r"))) 
+		{
+		ERR_clear_error();
+		BIO_printf(bio_err, "Warning: could not open file %s for "
+			   "reading, using serial number: 1\n", serialfile);
+		if (!ASN1_INTEGER_set(serial, 1)) goto err;
+		}
+	else
+		{
+		char buf[1024];
+		if (!a2i_ASN1_INTEGER(in, serial, buf, sizeof(buf)))
+			{
+			BIO_printf(bio_err, "unable to load number from %s\n",
+				   serialfile);
+			goto err;
+			}
+		if (!(bn = ASN1_INTEGER_to_BN(serial, NULL))) goto err;
+		ASN1_INTEGER_free(serial);
+		serial = NULL;
+		if (!BN_add_word(bn, 1)) goto err;
+		if (!(serial = BN_to_ASN1_INTEGER(bn, NULL))) goto err;
+		}
+	ret = 1;
+ err:
+	if (!ret)
+		{
+		ASN1_INTEGER_free(serial);
+		serial = NULL;
+		}
+	BIO_free_all(in);
+	BN_free(bn);
+	return serial;
+	}
+
+static int save_ts_serial(const char *serialfile, ASN1_INTEGER *serial)
+	{
+	int ret = 0;
+	BIO *out = NULL;
+
+	if (!(out = BIO_new_file(serialfile, "w"))) goto err;
+	if (i2a_ASN1_INTEGER(out, serial) <= 0) goto err;
+	if (BIO_puts(out, "\n") <= 0) goto err;
+	ret = 1;
+ err:
+	if (!ret)
+		BIO_printf(bio_err, "could not save serial number to %s\n",
+			   serialfile);
+	BIO_free_all(out);
+	return ret;
+	}
+
+/*
+ * Verify-related method definitions.
+ */
+
+static int verify_command(char *data, char *digest, char *queryfile,
+			  char *in, int token_in,
+			  char *ca_path, char *ca_file, char *untrusted)
+	{
+	BIO *in_bio = NULL;
+	PKCS7 *token = NULL;
+	TS_RESP *response = NULL;
+	TS_VERIFY_CTX *verify_ctx = NULL;
+	int ret = 0;
+
+	/* Decode the token (PKCS7) or response (TS_RESP) files. */
+	if (!(in_bio = BIO_new_file(in, "rb"))) goto end;
+	if (token_in)
+		{
+		if (!(token = d2i_PKCS7_bio(in_bio, NULL))) goto end;
+		}
+	else
+		{
+		if (!(response = d2i_TS_RESP_bio(in_bio, NULL))) goto end;
+		}
+
+	if (!(verify_ctx = create_verify_ctx(data, digest, queryfile, 
+					     ca_path, ca_file, untrusted)))
+		goto end;
+
+	/* Checking the token or response against the request. */
+	ret = token_in ?
+		TS_RESP_verify_token(verify_ctx, token) :
+		TS_RESP_verify_response(verify_ctx, response);
+
+ end:
+	printf("Verification: ");
+	if (ret)
+		printf("OK\n");
+	else
+		{
+		printf("FAILED\n");
+		/* Print errors, if there are any. */
+		ERR_print_errors(bio_err);
+		}
+	
+	/* Clean up. */
+	BIO_free_all(in_bio);
+	PKCS7_free(token);
+	TS_RESP_free(response);
+	TS_VERIFY_CTX_free(verify_ctx);
+	return ret;
+	}
+
+static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest, 
+					char *queryfile, 
+					char *ca_path, char *ca_file,
+					char *untrusted)
+	{
+	TS_VERIFY_CTX *ctx = NULL;
+	BIO *input = NULL;
+	TS_REQ *request = NULL;
+	int ret = 0;
+
+	if (data != NULL || digest != NULL)
+		{
+		if (!(ctx = TS_VERIFY_CTX_new())) goto err;
+		ctx->flags = TS_VFY_VERSION | TS_VFY_SIGNER;
+		if (data != NULL)
+			{
+			ctx->flags |= TS_VFY_DATA;
+			if (!(ctx->data = BIO_new_file(data, "rb"))) goto err;
+			}
+		else if (digest != NULL)
+			{
+			long imprint_len;
+			ctx->flags |= TS_VFY_IMPRINT;
+			if (!(ctx->imprint = string_to_hex(digest,
+							   &imprint_len)))
+				{
+				BIO_printf(bio_err, "invalid digest string\n");
+				goto err;
+				}
+			ctx->imprint_len = imprint_len;
+			}
+		
+		}
+	else if (queryfile != NULL)
+		{
+		/* The request has just to be read, decoded and converted to
+		   a verify context object. */
+		if (!(input = BIO_new_file(queryfile, "rb"))) goto err;
+		if (!(request = d2i_TS_REQ_bio(input, NULL))) goto err;
+		if (!(ctx = TS_REQ_to_TS_VERIFY_CTX(request, NULL))) goto err;
+		}
+	else
+		return NULL;
+
+	/* Add the signature verification flag and arguments. */
+	ctx->flags |= TS_VFY_SIGNATURE;
+
+	/* Initialising the X509_STORE object. */
+	if (!(ctx->store = create_cert_store(ca_path, ca_file))) goto err;
+
+	/* Loading untrusted certificates. */
+	if (untrusted && !(ctx->certs = TS_CONF_load_certs(untrusted))) 
+		goto err;
+
+	ret = 1;
+ err:
+	if (!ret)
+		{
+		TS_VERIFY_CTX_free(ctx);
+		ctx = NULL;
+		}
+	BIO_free_all(input);
+	TS_REQ_free(request);
+	return ctx;
+	}
+
+static X509_STORE *create_cert_store(char *ca_path, char *ca_file)
+	{
+	X509_STORE *cert_ctx = NULL;
+	X509_LOOKUP *lookup = NULL;
+	int i;
+
+	/* Creating the X509_STORE object. */
+	cert_ctx = X509_STORE_new();
+
+	/* Setting the callback for certificate chain verification. */
+	X509_STORE_set_verify_cb_func(cert_ctx, verify_cb);
+
+	/* Adding a trusted certificate directory source. */
+	if (ca_path)
+		{
+		lookup = X509_STORE_add_lookup(cert_ctx,
+					       X509_LOOKUP_hash_dir());
+		if (lookup == NULL)
+			{
+			BIO_printf(bio_err, "memory allocation failure\n");
+			goto err;
+			}
+		i = X509_LOOKUP_add_dir(lookup, ca_path, X509_FILETYPE_PEM);
+		if (!i)
+			{
+			BIO_printf(bio_err, "Error loading directory %s\n",
+				   ca_path);
+			goto err;
+			}
+		}
+
+	/* Adding a trusted certificate file source. */
+	if (ca_file)
+		{
+		lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
+		if (lookup == NULL)
+			{
+			BIO_printf(bio_err, "memory allocation failure\n");
+			goto err;
+			}
+		i = X509_LOOKUP_load_file(lookup, ca_file, X509_FILETYPE_PEM);
+		if (!i)
+			{
+			BIO_printf(bio_err, "Error loading file %s\n", ca_file);
+			goto err;
+			}
+		}
+
+	return cert_ctx;
+ err:
+	X509_STORE_free(cert_ctx);
+	return NULL;
+	}
+
+static int MS_CALLBACK verify_cb(int ok, X509_STORE_CTX *ctx)
+	{
+	/*
+	char buf[256];
+
+	if (!ok)
+		{
+		X509_NAME_oneline(X509_get_subject_name(ctx->current_cert),
+				  buf, sizeof(buf));
+		printf("%s\n", buf);
+		printf("error %d at %d depth lookup: %s\n",
+		       ctx->error, ctx->error_depth,
+			X509_verify_cert_error_string(ctx->error));
+		}
+	*/
+
+	return ok;
+	}
diff --git a/apps/tsget b/apps/tsget
new file mode 100644
index 0000000..ddae803
--- /dev/null
+++ b/apps/tsget
@@ -0,0 +1,195 @@
+#!/usr/bin/perl -w
+# Written by Zoltan Glozik <[email protected]>.
+# Copyright (c) 2002 The OpenTSA Project.  All rights reserved.
+$::version = '$Id: tsget,v 1.1 2006/02/12 23:11:21 ulf Exp $';
+
+use strict;
+use IO::Handle;
+use Getopt::Std;
+use File::Basename;
+use WWW::Curl::easy;
+
+use vars qw(%options);
+
+# Callback for reading the body.
+sub read_body {
+    my ($maxlength, $state) = @_;
+    my $return_data = "";
+    my $data_len = length ${$state->{data}};
+    if ($state->{bytes} < $data_len) {
+	$data_len = $data_len - $state->{bytes};
+	$data_len = $maxlength if $data_len > $maxlength;
+	$return_data = substr ${$state->{data}}, $state->{bytes}, $data_len;
+	$state->{bytes} += $data_len;
+    }
+    return $return_data;
+}
+
+# Callback for writing the body into a variable.
+sub write_body {
+    my ($data, $pointer) = @_;
+    ${$pointer} .= $data;
+    return length($data);
+}
+
+# Initialise a new Curl object.
+sub create_curl {
+    my $url = shift;
+
+    # Create Curl object.
+    my $curl = WWW::Curl::easy::new();
+
+    # Error-handling related options.
+    $curl->setopt(CURLOPT_VERBOSE, 1) if $options{d};
+    $curl->setopt(CURLOPT_FAILONERROR, 1);
+    $curl->setopt(CURLOPT_USERAGENT, "OpenTSA tsget.pl/" . (split / /, $::version)[2]);
+
+    # Options for POST method.
+    $curl->setopt(CURLOPT_UPLOAD, 1);
+    $curl->setopt(CURLOPT_CUSTOMREQUEST, "POST");
+    $curl->setopt(CURLOPT_HTTPHEADER,
+		["Content-Type: application/timestamp-query",
+		"Accept: application/timestamp-reply"]);
+    $curl->setopt(CURLOPT_READFUNCTION, \&read_body);
+    $curl->setopt(CURLOPT_HEADERFUNCTION, sub { return length($_[0]); });
+
+    # Options for getting the result.
+    $curl->setopt(CURLOPT_WRITEFUNCTION, \&write_body);
+
+    # SSL related options.
+    $curl->setopt(CURLOPT_SSLKEYTYPE, "PEM");
+    $curl->setopt(CURLOPT_SSL_VERIFYPEER, 1);	# Verify server's certificate.
+    $curl->setopt(CURLOPT_SSL_VERIFYHOST, 2);	# Check server's CN.
+    $curl->setopt(CURLOPT_SSLKEY, $options{k}) if defined($options{k});
+    $curl->setopt(CURLOPT_SSLKEYPASSWD, $options{p}) if defined($options{p});
+    $curl->setopt(CURLOPT_SSLCERT, $options{c}) if defined($options{c});
+    $curl->setopt(CURLOPT_CAINFO, $options{C}) if defined($options{C});
+    $curl->setopt(CURLOPT_CAPATH, $options{P}) if defined($options{P});
+    $curl->setopt(CURLOPT_RANDOM_FILE, $options{r}) if defined($options{r});
+    $curl->setopt(CURLOPT_EGDSOCKET, $options{g}) if defined($options{g});
+
+    # Setting destination.
+    $curl->setopt(CURLOPT_URL, $url);
+
+    return $curl;
+}
+
+# Send a request and returns the body back.
+sub get_timestamp {
+    my $curl = shift;
+    my $body = shift;
+    my $ts_body;
+    local $::error_buf;
+
+    # Error-handling related options.
+    $curl->setopt(CURLOPT_ERRORBUFFER, "::error_buf");
+
+    # Options for POST method.
+    $curl->setopt(CURLOPT_INFILE, {data => $body, bytes => 0});
+    $curl->setopt(CURLOPT_INFILESIZE, length(${$body}));
+
+    # Options for getting the result.
+    $curl->setopt(CURLOPT_FILE, \$ts_body);
+
+    # Send the request...
+    my $error_code = $curl->perform();
+    my $error_string;
+    if ($error_code != 0) {
+        my $http_code = $curl->getinfo(CURLINFO_HTTP_CODE);
+	$error_string = "could not get timestamp";
+	$error_string .= ", http code: $http_code" unless $http_code == 0;
+	$error_string .= ", curl code: $error_code";
+	$error_string .= " ($::error_buf)" if defined($::error_buf);
+    } else {
+        my $ct = $curl->getinfo(CURLINFO_CONTENT_TYPE);
+	if (lc($ct) ne "application/timestamp-reply") {
+	    $error_string = "unexpected content type returned: $ct";
+        }
+    }
+    return ($ts_body, $error_string);
+
+}
+
+# Print usage information and exists.
+sub usage {
+
+    print STDERR "usage: $0 -h <server_url> [-e <extension>] [-o <output>] ";
+    print STDERR "[-v] [-d] [-k <private_key.pem>] [-p <key_password>] ";
+    print STDERR "[-c <client_cert.pem>] [-C <CA_certs.pem>] [-P <CA_path>] ";
+    print STDERR "[-r <file:file...>] [-g <EGD_socket>] [<request>]...\n";
+    exit 1;
+}
+
+# ----------------------------------------------------------------------
+#   Main program
+# ----------------------------------------------------------------------
+
+# Getting command-line options (default comes from TSGET environment variable).
+my $getopt_arg =  "h:e:o:vdk:p:c:C:P:r:g:";
+if (exists $ENV{TSGET}) {
+    my @old_argv = @ARGV;
+    @ARGV = split /\s+/, $ENV{TSGET};
+    getopts($getopt_arg, \%options) or usage;
+    @ARGV = @old_argv;
+}
+getopts($getopt_arg, \%options) or usage;
+
+# Checking argument consistency.
+if (!exists($options{h}) || (@ARGV == 0 && !exists($options{o}))
+    || (@ARGV > 1 && exists($options{o}))) {
+    print STDERR "Inconsistent command line options.\n";
+    usage;
+}
+# Setting defaults.
+@ARGV = ("-") unless @ARGV != 0;
+$options{e} = ".tsr" unless defined($options{e});
+
+# Processing requests.
+my $curl = create_curl $options{h};
+undef $/;   # For reading whole files.
+REQUEST: foreach (@ARGV) {
+    my $input = $_;
+    my ($base, $path) = fileparse($input, '\.[^.]*');
+    my $output_base = $base . $options{e};
+    my $output = defined($options{o}) ? $options{o} : $path . $output_base;
+
+    STDERR->printflush("$input: ") if $options{v};
+    # Read request.
+    my $body;
+    if ($input eq "-") {
+	# Read the request from STDIN;
+	$body = <STDIN>;
+    } else {
+	# Read the request from file.
+        open INPUT, "<" . $input
+	    or warn("$input: could not open input file: $!\n"), next REQUEST;
+        $body = <INPUT>;
+        close INPUT
+	    or warn("$input: could not close input file: $!\n"), next REQUEST;
+    }
+
+    # Send request.
+    STDERR->printflush("sending request") if $options{v};
+
+    my ($ts_body, $error) = get_timestamp $curl, \$body;
+    if (defined($error)) {
+	die "$input: fatal error: $error\n";
+    }
+    STDERR->printflush(", reply received") if $options{v};
+
+    # Write response.
+    if ($output eq "-") {
+	# Write to STDOUT.
+        print $ts_body;
+    } else {
+	# Write to file.
+        open OUTPUT, ">", $output
+	    or warn("$output: could not open output file: $!\n"), next REQUEST;
+        print OUTPUT $ts_body;
+        close OUTPUT
+	    or warn("$output: could not close output file: $!\n"), next REQUEST;
+    }
+    STDERR->printflush(", $output written.\n") if $options{v};
+}
+$curl->cleanup();
+WWW::Curl::easy::global_cleanup();
diff --git a/apps/version.c b/apps/version.c
index 69ef3e1..e9555cb 100644
--- a/apps/version.c
+++ b/apps/version.c
@@ -167,7 +167,7 @@
 			date=version=cflags=options=platform=dir=1;
 		else
 			{
-			BIO_printf(bio_err,"usage:version -[avbofp]\n");
+			BIO_printf(bio_err,"usage:version -[avbofpd]\n");
 			ret=1;
 			goto end;
 			}
diff --git a/apps/x509.c b/apps/x509.c
index d904d34..6debce4 100644
--- a/apps/x509.c
+++ b/apps/x509.c
@@ -114,7 +114,7 @@
 " -alias          - output certificate alias\n",
 " -noout          - no certificate output\n",
 " -ocspid         - print OCSP hash values for the subject name and public key\n",
-" -ocspurl        - print OCSP Responder URL(s)\n",
+" -ocsp_uri       - print OCSP Responder URL(s)\n",
 " -trustout       - output a \"trusted\" certificate\n",
 " -clrtrust       - clear all trusted purposes\n",
 " -clrreject      - clear all rejected purposes\n",
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 <[email protected]>
+ * @author Antoon Bosselaers <[email protected]>
+ * @author Paulo Barreto <[email protected]>
+ *
+ * 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.
+ *
+ *					<[email protected]>
+ */
+
+
+#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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) 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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+#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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) 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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+/* 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Stephen Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) 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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+/* 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 ([email protected]) 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
+ *    [email protected].
+ *
+ * 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) 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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+#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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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/include/openssl/md2.h b/crypto/bn/bn_opt.c
similarity index 79%
copy from include/openssl/md2.h
copy to crypto/bn/bn_opt.c
index a46120e..21cbb38 100644
--- a/include/openssl/md2.h
+++ b/crypto/bn/bn_opt.c
@@ -1,5 +1,5 @@
-/* crypto/md/md2.h */
-/* Copyright (C) 1995-1997 Eric Young ([email protected])
+/* crypto/bn/bn_opt.c */
+/* Copyright (C) 1995-1998 Eric Young ([email protected])
  * All rights reserved.
  *
  * This package is an SSL implementation written
@@ -56,37 +56,32 @@
  * [including the GNU Public Licence.]
  */
 
-#ifndef HEADER_MD2_H
-#define HEADER_MD2_H
-
-#include <openssl/opensslconf.h> /* OPENSSL_NO_MD2, MD2_INT */
-#ifdef OPENSSL_NO_MD2
-#error MD2 is disabled.
-#endif
-#include <stddef.h>
-
-#define MD2_DIGEST_LENGTH	16
-#define MD2_BLOCK       	16
-
-#ifdef  __cplusplus
-extern "C" {
+#ifndef BN_DEBUG
+# undef NDEBUG /* avoid conflicting definitions */
+# define NDEBUG
 #endif
 
-typedef struct MD2state_st
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include "cryptlib.h"
+#include "bn_lcl.h"
+
+char *BN_options(void)
 	{
-	unsigned int num;
-	unsigned char data[MD2_BLOCK];
-	MD2_INT cksm[MD2_BLOCK];
-	MD2_INT state[MD2_BLOCK];
-	} MD2_CTX;
+	static int init=0;
+	static char data[16];
 
-const char *MD2_options(void);
-int MD2_Init(MD2_CTX *c);
-int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len);
-int MD2_Final(unsigned char *md, MD2_CTX *c);
-unsigned char *MD2(const unsigned char *d, size_t n,unsigned char *md);
-#ifdef  __cplusplus
-}
+	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
-
-#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 ([email protected]) 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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+#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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+#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 <[email protected]>
+#
+# 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 <[email protected]>");
+
+&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 <[email protected]>
+#
+# 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 <[email protected]>"
+___
+}
+
+# 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 ([email protected]) for the OpenSSL
+/* Written by Stephen Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Stephen Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Stephen Henson ([email protected]) 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/include/openssl/md2.h b/crypto/des/des_lib.c
similarity index 77%
copy from include/openssl/md2.h
copy to crypto/des/des_lib.c
index a46120e..d4b3047 100644
--- a/include/openssl/md2.h
+++ b/crypto/des/des_lib.c
@@ -1,5 +1,5 @@
-/* crypto/md/md2.h */
-/* Copyright (C) 1995-1997 Eric Young ([email protected])
+/* crypto/des/ecb_enc.c */
+/* Copyright (C) 1995-1998 Eric Young ([email protected])
  * All rights reserved.
  *
  * This package is an SSL implementation written
@@ -56,37 +56,51 @@
  * [including the GNU Public Licence.]
  */
 
-#ifndef HEADER_MD2_H
-#define HEADER_MD2_H
+#include "des_locl.h"
+#include "des_ver.h"
+#include <openssl/opensslv.h>
+#include <openssl/bio.h>
 
-#include <openssl/opensslconf.h> /* OPENSSL_NO_MD2, MD2_INT */
-#ifdef OPENSSL_NO_MD2
-#error MD2 is disabled.
-#endif
-#include <stddef.h>
+OPENSSL_GLOBAL const char libdes_version[]="libdes" OPENSSL_VERSION_PTEXT;
+OPENSSL_GLOBAL const char DES_version[]="DES" OPENSSL_VERSION_PTEXT;
 
-#define MD2_DIGEST_LENGTH	16
-#define MD2_BLOCK       	16
-
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-typedef struct MD2state_st
+const char *DES_options(void)
 	{
-	unsigned int num;
-	unsigned char data[MD2_BLOCK];
-	MD2_INT cksm[MD2_BLOCK];
-	MD2_INT state[MD2_BLOCK];
-	} MD2_CTX;
+	static int init=1;
+	static char buf[32];
 
-const char *MD2_options(void);
-int MD2_Init(MD2_CTX *c);
-int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len);
-int MD2_Final(unsigned char *md, MD2_CTX *c);
-unsigned char *MD2(const unsigned char *d, size_t n,unsigned char *md);
-#ifdef  __cplusplus
-}
-#endif
+	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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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/include/openssl/md2.h b/crypto/dsa/dsa_utl.c
similarity index 79%
rename from include/openssl/md2.h
rename to crypto/dsa/dsa_utl.c
index a46120e..24c021d 100644
--- a/include/openssl/md2.h
+++ b/crypto/dsa/dsa_utl.c
@@ -1,5 +1,5 @@
-/* crypto/md/md2.h */
-/* Copyright (C) 1995-1997 Eric Young ([email protected])
+/* crypto/dsa/dsa_lib.c */
+/* Copyright (C) 1995-1998 Eric Young ([email protected])
  * All rights reserved.
  *
  * This package is an SSL implementation written
@@ -56,37 +56,40 @@
  * [including the GNU Public Licence.]
  */
 
-#ifndef HEADER_MD2_H
-#define HEADER_MD2_H
+/* Original version from Steven Schoch <[email protected]> */
 
-#include <openssl/opensslconf.h> /* OPENSSL_NO_MD2, MD2_INT */
-#ifdef OPENSSL_NO_MD2
-#error MD2 is disabled.
+#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
-#include <stddef.h>
-
-#define MD2_DIGEST_LENGTH	16
-#define MD2_BLOCK       	16
-
-#ifdef  __cplusplus
-extern "C" {
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
 #endif
 
-typedef struct MD2state_st
+DSA_SIG *DSA_SIG_new(void)
 	{
-	unsigned int num;
-	unsigned char data[MD2_BLOCK];
-	MD2_INT cksm[MD2_BLOCK];
-	MD2_INT state[MD2_BLOCK];
-	} MD2_CTX;
+	DSA_SIG *sig;
+	sig = OPENSSL_malloc(sizeof(DSA_SIG));
+	if (!sig)
+		return NULL;
+	sig->r = NULL;
+	sig->s = NULL;
+	return sig;
+	}
 
-const char *MD2_options(void);
-int MD2_Init(MD2_CTX *c);
-int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len);
-int MD2_Final(unsigned char *md, MD2_CTX *c);
-unsigned char *MD2(const unsigned char *d, size_t n,unsigned char *md);
-#ifdef  __cplusplus
-}
-#endif
+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);
+		}
+	}
 
-#endif
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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young ([email protected])
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young ([email protected]).
+ * 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 ([email protected]).
+ * 
+ * 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 ([email protected])"
+ *    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 ([email protected])"
+ * 
+ * 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 ([email protected]) for the OpenSSL
+/* Written by Stephen Henson ([email protected]) 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/include/openssl/md2.h b/crypto/err/err_bio.c
similarity index 79%
copy from include/openssl/md2.h
copy to crypto/err/err_bio.c
index a46120e..a42f804 100644
--- a/include/openssl/md2.h
+++ b/crypto/err/err_bio.c
@@ -1,5 +1,5 @@
-/* crypto/md/md2.h */
-/* Copyright (C) 1995-1997 Eric Young ([email protected])
+/* crypto/err/err_prn.c */
+/* Copyright (C) 1995-1998 Eric Young ([email protected])
  * All rights reserved.
  *
  * This package is an SSL implementation written
@@ -56,37 +56,20 @@
  * [including the GNU Public Licence.]
  */
 
-#ifndef HEADER_MD2_H
-#define HEADER_MD2_H
+#include <stdio.h>
+#include "cryptlib.h"
+#include <openssl/lhash.h>
+#include <openssl/crypto.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
 
-#include <openssl/opensslconf.h> /* OPENSSL_NO_MD2, MD2_INT */
-#ifdef OPENSSL_NO_MD2
-#error MD2 is disabled.
-#endif
-#include <stddef.h>
-
-#define MD2_DIGEST_LENGTH	16
-#define MD2_BLOCK       	16
-
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-typedef struct MD2state_st
+static int print_bio(const char *str, size_t len, void *bp)
 	{
-	unsigned int num;
-	unsigned char data[MD2_BLOCK];
-	MD2_INT cksm[MD2_BLOCK];
-	MD2_INT state[MD2_BLOCK];
-	} MD2_CTX;
+	return BIO_write((BIO *)bp, str, len);
+	}
+void ERR_print_errors(BIO *bp)
+	{
+	ERR_print_errors_cb(print_bio, bp);
+	}
 
-const char *MD2_options(void);
-int MD2_Init(MD2_CTX *c);
-int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len);
-int MD2_Final(unsigned char *md, MD2_CTX *c);
-unsigned char *MD2(const unsigned char *d, size_t n,unsigned char *md);
-#ifdef  __cplusplus
-}
-#endif
-
-#endif
+	
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 ([email protected])
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young ([email protected]).
+ * 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 ([email protected]).
+ * 
+ * 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 ([email protected])"
+ *    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 ([email protected])"
+ * 
+ * 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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+#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 ([email protected])
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young ([email protected]).
+ * 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 ([email protected]).
+ * 
+ * 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 ([email protected])"
+ *    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 ([email protected])"
+ * 
+ * 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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+#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 ([email protected])
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young ([email protected]).
+ * 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 ([email protected]).
+ * 
+ * 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 ([email protected])"
+ *    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 ([email protected])"
+ * 
+ * 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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+#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 ([email protected])
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young ([email protected]).
+ * 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 ([email protected]).
+ * 
+ * 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 ([email protected])"
+ *    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 ([email protected])"
+ * 
+ * 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 ([email protected]) for the OpenSSL
+/* Written by Stephen Henson ([email protected]) 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 ([email protected]) 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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+#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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+/* 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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+/* 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 ([email protected]) 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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+#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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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/include/openssl/md2.h b/crypto/rand/rand_eng.c
similarity index 63%
copy from include/openssl/md2.h
copy to crypto/rand/rand_eng.c
index a46120e..1669cef 100644
--- a/include/openssl/md2.h
+++ b/crypto/rand/rand_eng.c
@@ -1,5 +1,5 @@
-/* crypto/md/md2.h */
-/* Copyright (C) 1995-1997 Eric Young ([email protected])
+/* crypto/rand/rand_lib.c */
+/* Copyright (C) 1995-1998 Eric Young ([email protected])
  * All rights reserved.
  *
  * This package is an SSL implementation written
@@ -56,37 +56,97 @@
  * [including the GNU Public Licence.]
  */
 
-#ifndef HEADER_MD2_H
-#define HEADER_MD2_H
-
-#include <openssl/opensslconf.h> /* OPENSSL_NO_MD2, MD2_INT */
-#ifdef OPENSSL_NO_MD2
-#error MD2 is disabled.
-#endif
-#include <stddef.h>
-
-#define MD2_DIGEST_LENGTH	16
-#define MD2_BLOCK       	16
-
-#ifdef  __cplusplus
-extern "C" {
+#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
 
-typedef struct MD2state_st
+#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)
 	{
-	unsigned int num;
-	unsigned char data[MD2_BLOCK];
-	MD2_INT cksm[MD2_BLOCK];
-	MD2_INT state[MD2_BLOCK];
-	} MD2_CTX;
+	if(funct_ref)
+		{
+		ENGINE_finish(funct_ref);
+		funct_ref = NULL;
+		}
+	*pmeth = meth;
+	return 1;
+	}
 
-const char *MD2_options(void);
-int MD2_Init(MD2_CTX *c);
-int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len);
-int MD2_Final(unsigned char *md, MD2_CTX *c);
-unsigned char *MD2(const unsigned char *d, size_t n,unsigned char *md);
-#ifdef  __cplusplus
-}
-#endif
+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 ([email protected]) 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
+ *    [email protected].
+ *
+ * 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 @@
 		 *
 		 *				<[email protected]>
 		 */
-		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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected])
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young ([email protected]).
+ * 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 ([email protected]).
+ * 
+ * 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 ([email protected])"
+ *    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 ([email protected])"
+ * 
+ * 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected])
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young ([email protected]).
+ * 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 ([email protected]).
+ * 
+ * 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 ([email protected])"
+ *    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 ([email protected])"
+ * 
+ * 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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 ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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
diff --git a/e_os.h b/e_os.h
index acc6a15..9c5c6fd 100644
--- a/e_os.h
+++ b/e_os.h
@@ -269,6 +269,7 @@
 #      define _WIN32_WINNT 0x0400
 #    endif
 #    include <windows.h>
+#    include <stdio.h>
 #    include <stddef.h>
 #    include <errno.h>
 #    include <string.h>
@@ -284,13 +285,38 @@
 #    endif
 #    include <malloc.h>
 #    if defined(_MSC_VER) && _MSC_VER<=1200 && defined(_MT) && defined(isspace)
-       /* compensate for bug is VC6 ctype.h */
+       /* compensate for bug in VC6 ctype.h */
 #      undef isspace
 #      undef isdigit
 #      undef isalnum
 #      undef isupper
 #      undef isxdigit
 #    endif
+#    if defined(_MSC_VER) && !defined(_DLL) && defined(stdin)
+#      if _MSC_VER>=1300
+#        undef stdin
+#        undef stdout
+#        undef stderr
+         FILE *__iob_func();
+#        define stdin  (&__iob_func()[0])
+#        define stdout (&__iob_func()[1])
+#        define stderr (&__iob_func()[2])
+#      elif defined(I_CAN_LIVE_WITH_LNK4049)
+#        undef stdin
+#        undef stdout
+#        undef stderr
+         /* pre-1300 has __p__iob(), but it's available only in msvcrt.lib,
+          * or in other words with /MD. Declaring implicit import, i.e.
+          * with _imp_ prefix, works correctly with all compiler options,
+          * but without /MD results in LINK warning LNK4049:
+          * 'locally defined symbol "__iob" imported'.
+          */
+         extern FILE *_imp___iob;
+#        define stdin  (&_imp___iob[0])
+#        define stdout (&_imp___iob[1])
+#        define stderr (&_imp___iob[2])
+#      endif
+#    endif
 #  endif
 #  include <io.h>
 #  include <fcntl.h>
diff --git a/import_openssl.sh b/import_openssl.sh
new file mode 100755
index 0000000..dda6bce
--- /dev/null
+++ b/import_openssl.sh
@@ -0,0 +1,99 @@
+#!/bin/bash
+#
+# This script imports new versions of OpenSSL (http://openssl.org/source) into the
+# Android source tree.  To run, (1) fetch the appropriate tarball from the OpenSSL repository,
+# (2) check the gpg/pgp signature, and then (3) run:
+#   ./import_openssl.sh openssl-*.tar.gz
+#
+# IMPORTANT: See README.openssl for additional details.
+
+set -e
+
+die() {
+  echo $1
+  exit 255
+}
+
+if [ $# != 1 ]; then
+  die "Usage: ./import_openssl.sh /path/to/openssl-*.tar.gz"
+fi
+
+OPENSSL_SOURCE=$1
+
+if [ ! -f openssl.config ]; then
+  die "openssl.config not found"
+fi
+
+if [ ! -f openssl.version ]; then
+  die "openssl.version not found"
+fi
+
+if [ ! -d patches ]; then
+  die "OpenSSL patch directory patches/ not found"
+fi
+
+source openssl.config
+source openssl.version
+
+if [ "$CONFIGURE_ARGS" == "" ]; then
+  die "Invalid openssl.config; see README.openssl for more information"
+fi
+
+NEW_OPENSSL_VERSION=`expr match "$OPENSSL_SOURCE" '.*-\(.*\).tar.gz' || true`
+if [ "$NEW_OPENSSL_VERSION" == "" ]; then
+  die "Invalid openssl source filename: $OPENSSL_SOURCE"
+fi
+
+# Remove old source
+if [ "$OPENSSL_VERSION" == "" ]; then
+  die "OPENSSL_VERSION not declared in openssl.version"
+else
+  rm -rf openssl-$OPENSSL_VERSION/
+fi
+
+# Process new source
+OPENSSL_VERSION=$NEW_OPENSSL_VERSION
+rm -rf openssl-$OPENSSL_VERSION/     # remove stale files
+tar -zxf $OPENSSL_SOURCE
+cd openssl-$OPENSSL_VERSION
+
+./Configure $CONFIGURE_ARGS
+
+# TODO(): Fixup android-config.mk
+
+cp -f LICENSE ../NOTICE
+touch ../MODULE_LICENSE_BSD_LIKE
+
+# Prune unnecessary sources
+rm -rf $UNNEEDED_SOURCES
+
+# Avoid checking in symlinks
+for i in `find include/openssl -type l`; do
+  target=`readlink $i`
+  rm -f $i
+  if [ -f include/openssl/$target ]; then
+    cp include/openssl/$target $i
+  fi
+done
+
+# Apply appropriate patches
+for i in $OPENSSL_PATCHES; do
+  patch -p1 < ../patches/$i
+done
+
+# Copy Makefiles
+cp ../patches/apps_Android.mk apps/Android.mk
+cp ../patches/crypto_Android.mk crypto/Android.mk
+cp ../patches/ssl_Android.mk ssl/Android.mk
+
+cd ..
+cp -af openssl-$OPENSSL_VERSION/include .
+rm -rf apps/
+mv openssl-$OPENSSL_VERSION/apps .
+rm -rf ssl/
+mv openssl-$OPENSSL_VERSION/ssl .
+rm -rf crypto/
+mv openssl-$OPENSSL_VERSION/crypto .
+rm -f e_os.h e_os2.h
+mv openssl-$OPENSSL_VERSION/e_os.h openssl-$OPENSSL_VERSION/e_os2.h .
+rm -rf openssl-$OPENSSL_VERSION/
diff --git a/include/openssl/aes.h b/include/openssl/aes.h
index baf0222..450f2b4 100644
--- a/include/openssl/aes.h
+++ b/include/openssl/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/include/openssl/asn1.h b/include/openssl/asn1.h
index 424cd34..e338522 100644
--- a/include/openssl/asn1.h
+++ b/include/openssl/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/include/openssl/asn1t.h b/include/openssl/asn1t.h
index bf315e6..ac14f94 100644
--- a/include/openssl/asn1t.h
+++ b/include/openssl/asn1t.h
@@ -1,5 +1,5 @@
 /* asn1t.h */
-/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
  * project 2000.
  */
 /* ====================================================================
diff --git a/include/openssl/bn.h b/include/openssl/bn.h
index 6d754d5..f1719a5 100644
--- a/include/openssl/bn.h
+++ b/include/openssl/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/include/openssl/crypto.h b/include/openssl/crypto.h
index d2b5ffe..0e4fb07 100644
--- a/include/openssl/crypto.h
+++ b/include/openssl/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/include/openssl/dh.h b/include/openssl/dh.h
index ccdf35a..10475ac 100644
--- a/include/openssl/dh.h
+++ b/include/openssl/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/include/openssl/dsa.h b/include/openssl/dsa.h
index 3a8fe5b..702c50d 100644
--- a/include/openssl/dsa.h
+++ b/include/openssl/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/include/openssl/dtls1.h b/include/openssl/dtls1.h
index a663cf8..f159d37 100644
--- a/include/openssl/dtls1.h
+++ b/include/openssl/dtls1.h
@@ -70,7 +70,10 @@
 #define DTLS1_VERSION			0xFEFF
 #define DTLS1_BAD_VER			0x0100
 
+#if 0
+/* this alert description is not specified anywhere... */
 #define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE    110
+#endif
 
 /* lengths of messages */
 #define DTLS1_COOKIE_LENGTH                     32
@@ -84,7 +87,11 @@
 
 #define DTLS1_CCS_HEADER_LENGTH                  1
 
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
 #define DTLS1_AL_HEADER_LENGTH                   7
+#else
+#define DTLS1_AL_HEADER_LENGTH                   2
+#endif
 
 
 typedef struct dtls1_bitmap_st
diff --git a/include/openssl/engine.h b/include/openssl/engine.h
index 3ec5933..f503595 100644
--- a/include/openssl/engine.h
+++ b/include/openssl/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/include/openssl/err.h b/include/openssl/err.h
index bf28fce..dcac415 100644
--- a/include/openssl/err.h
+++ b/include/openssl/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/include/openssl/evp.h b/include/openssl/evp.h
index bdd3b7e..79c0971 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/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/include/openssl/fips.h b/include/openssl/fips.h
new file mode 100644
index 0000000..42bdcf2
--- /dev/null
+++ b/include/openssl/fips.h
@@ -0,0 +1,163 @@
+/* ====================================================================
+ * Copyright (c) 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
+ *    [email protected].
+ *
+ * 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/opensslconf.h>
+
+#ifndef OPENSSL_FIPS
+#error FIPS is disabled.
+#endif
+
+#ifdef OPENSSL_FIPS
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+struct dsa_st;
+struct evp_pkey_st;
+struct env_md_st;
+struct evp_cipher_st;
+struct evp_cipher_ctx_st;
+
+int FIPS_mode_set(int onoff);
+int FIPS_mode(void);
+const void *FIPS_rand_check(void);
+int FIPS_selftest_failed(void);
+void FIPS_selftest_check(void);
+void FIPS_corrupt_sha1(void);
+int FIPS_selftest_sha1(void);
+void FIPS_corrupt_aes(void);
+int FIPS_selftest_aes(void);
+void FIPS_corrupt_des(void);
+int FIPS_selftest_des(void);
+void FIPS_corrupt_rsa(void);
+void FIPS_corrupt_rsa_keygen(void);
+int FIPS_selftest_rsa(void);
+void FIPS_corrupt_dsa(void);
+void FIPS_corrupt_dsa_keygen(void);
+int FIPS_selftest_dsa(void);
+void FIPS_corrupt_rng(void);
+void FIPS_rng_stick(void);
+int FIPS_selftest_rng(void);
+int FIPS_selftest_hmac(void);
+
+int fips_pkey_signature_test(struct evp_pkey_st *pkey,
+			const unsigned char *tbs, int tbslen,
+			const unsigned char *kat, unsigned int katlen,
+			const struct env_md_st *digest, unsigned int md_flags,
+			const char *fail_str);
+
+int fips_cipher_test(struct evp_cipher_ctx_st *ctx,
+			const struct evp_cipher_st *cipher,
+			const unsigned char *key,
+			const unsigned char *iv,
+			const unsigned char *plaintext,
+			const unsigned char *ciphertext,
+			int len);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_FIPS_strings(void);
+
+/* Error codes for the FIPS functions. */
+
+/* Function codes. */
+#define FIPS_F_DH_BUILTIN_GENPARAMS			 100
+#define FIPS_F_DSA_BUILTIN_PARAMGEN			 101
+#define FIPS_F_DSA_DO_SIGN				 102
+#define FIPS_F_DSA_DO_VERIFY				 103
+#define FIPS_F_EVP_CIPHERINIT_EX			 124
+#define FIPS_F_EVP_DIGESTINIT_EX			 125
+#define FIPS_F_FIPS_CHECK_DSA				 104
+#define FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT		 105
+#define FIPS_F_FIPS_CHECK_RSA				 106
+#define FIPS_F_FIPS_DSA_CHECK				 107
+#define FIPS_F_FIPS_MODE_SET				 108
+#define FIPS_F_FIPS_PKEY_SIGNATURE_TEST			 109
+#define FIPS_F_FIPS_SELFTEST_AES			 110
+#define FIPS_F_FIPS_SELFTEST_DES			 111
+#define FIPS_F_FIPS_SELFTEST_DSA			 112
+#define FIPS_F_FIPS_SELFTEST_HMAC			 113
+#define FIPS_F_FIPS_SELFTEST_RNG			 114
+#define FIPS_F_FIPS_SELFTEST_SHA1			 115
+#define FIPS_F_HASH_FINAL				 123
+#define FIPS_F_RSA_BUILTIN_KEYGEN			 116
+#define FIPS_F_RSA_EAY_PRIVATE_DECRYPT			 117
+#define FIPS_F_RSA_EAY_PRIVATE_ENCRYPT			 118
+#define FIPS_F_RSA_EAY_PUBLIC_DECRYPT			 119
+#define FIPS_F_RSA_EAY_PUBLIC_ENCRYPT			 120
+#define FIPS_F_RSA_X931_GENERATE_KEY_EX			 121
+#define FIPS_F_SSLEAY_RAND_BYTES			 122
+
+/* Reason codes. */
+#define FIPS_R_CANNOT_READ_EXE				 103
+#define FIPS_R_CANNOT_READ_EXE_DIGEST			 104
+#define FIPS_R_CONTRADICTING_EVIDENCE			 114
+#define FIPS_R_EXE_DIGEST_DOES_NOT_MATCH		 105
+#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH		 110
+#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED 111
+#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING 112
+#define FIPS_R_FIPS_MODE_ALREADY_SET			 102
+#define FIPS_R_FIPS_SELFTEST_FAILED			 106
+#define FIPS_R_INVALID_KEY_LENGTH			 109
+#define FIPS_R_KEY_TOO_SHORT				 108
+#define FIPS_R_NON_FIPS_METHOD				 100
+#define FIPS_R_PAIRWISE_TEST_FAILED			 107
+#define FIPS_R_RSA_DECRYPT_ERROR			 115
+#define FIPS_R_RSA_ENCRYPT_ERROR			 116
+#define FIPS_R_SELFTEST_FAILED				 101
+#define FIPS_R_TEST_FAILURE				 117
+#define FIPS_R_UNSUPPORTED_PLATFORM			 113
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
diff --git a/include/openssl/fips_rand.h b/include/openssl/fips_rand.h
new file mode 100644
index 0000000..a175aaf
--- /dev/null
+++ b/include/openssl/fips_rand.h
@@ -0,0 +1,77 @@
+/* ====================================================================
+ * Copyright (c) 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
+ *    [email protected].
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef HEADER_FIPS_RAND_H
+#define HEADER_FIPS_RAND_H
+
+#include "des.h"
+
+#ifdef OPENSSL_FIPS
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+int FIPS_rand_set_key(const unsigned char *key, FIPS_RAND_SIZE_T keylen);
+int FIPS_rand_seed(const void *buf, FIPS_RAND_SIZE_T num);
+int FIPS_rand_bytes(unsigned char *out, FIPS_RAND_SIZE_T outlen);
+
+int FIPS_rand_test_mode(void);
+void FIPS_rand_reset(void);
+int FIPS_rand_set_dt(unsigned char *dt);
+
+int FIPS_rand_status(void);
+
+const RAND_METHOD *FIPS_rand_method(void);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+#endif
diff --git a/include/openssl/hmac.h b/include/openssl/hmac.h
index 719fc40..fc38ffb 100644
--- a/include/openssl/hmac.h
+++ b/include/openssl/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/include/openssl/md4.h b/include/openssl/md4.h
index 5598c93..ba1fe4a 100644
--- a/include/openssl/md4.h
+++ b/include/openssl/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/include/openssl/md5.h b/include/openssl/md5.h
index dbdc0e1..0761f84 100644
--- a/include/openssl/md5.h
+++ b/include/openssl/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/include/openssl/obj_mac.h b/include/openssl/obj_mac.h
index 76d5ec9..ad5f7cf 100644
--- a/include/openssl/obj_mac.h
+++ b/include/openssl/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/include/openssl/opensslconf.h b/include/openssl/opensslconf.h
index 14e04f9..4aa0330 100644
--- a/include/openssl/opensslconf.h
+++ b/include/openssl/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/include/openssl/opensslv.h b/include/openssl/opensslv.h
index b308894..c6207f7 100644
--- a/include/openssl/opensslv.h
+++ b/include/openssl/opensslv.h
@@ -25,11 +25,11 @@
  * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
  *  major minor fix final patch/beta)
  */
-#define OPENSSL_VERSION_NUMBER	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/include/openssl/ossl_typ.h b/include/openssl/ossl_typ.h
index 345fb1d..0e7a380 100644
--- a/include/openssl/ossl_typ.h
+++ b/include/openssl/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/include/openssl/pem.h b/include/openssl/pem.h
index 670afa6..6c193f1 100644
--- a/include/openssl/pem.h
+++ b/include/openssl/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/include/openssl/pkcs12.h b/include/openssl/pkcs12.h
index a2d7e35..4bee605 100644
--- a/include/openssl/pkcs12.h
+++ b/include/openssl/pkcs12.h
@@ -1,5 +1,5 @@
 /* pkcs12.h */
-/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
diff --git a/include/openssl/pq_compat.h b/include/openssl/pq_compat.h
index fd36578..7b2c327 100644
--- a/include/openssl/pq_compat.h
+++ b/include/openssl/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/include/openssl/rand.h b/include/openssl/rand.h
index ac6c021..ea89153 100644
--- a/include/openssl/rand.h
+++ b/include/openssl/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/include/openssl/rc2.h b/include/openssl/rc2.h
index 34c8362..e542ec9 100644
--- a/include/openssl/rc2.h
+++ b/include/openssl/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/include/openssl/rc4.h b/include/openssl/rc4.h
index 7aec04f..2d8620d 100644
--- a/include/openssl/rc4.h
+++ b/include/openssl/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/include/openssl/ripemd.h b/include/openssl/ripemd.h
index 033a596..3b6d043 100644
--- a/include/openssl/ripemd.h
+++ b/include/openssl/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/include/openssl/rsa.h b/include/openssl/rsa.h
index 6b5e4f8..5bb932a 100644
--- a/include/openssl/rsa.h
+++ b/include/openssl/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/include/openssl/safestack.h b/include/openssl/safestack.h
index 78cc485..40b1790 100644
--- a/include/openssl/safestack.h
+++ b/include/openssl/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/include/openssl/sha.h b/include/openssl/sha.h
index eed44d7..47a2c29 100644
--- a/include/openssl/sha.h
+++ b/include/openssl/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/include/openssl/ssl.h b/include/openssl/ssl.h
index 6df921f..ff8a128 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -252,6 +252,7 @@
 #define SSL_TXT_LOW		"LOW"
 #define SSL_TXT_MEDIUM		"MEDIUM"
 #define SSL_TXT_HIGH		"HIGH"
+#define SSL_TXT_FIPS		"FIPS"
 #define SSL_TXT_kFZA		"kFZA"
 #define	SSL_TXT_aFZA		"aFZA"
 #define SSL_TXT_eFZA		"eFZA"
@@ -361,9 +362,6 @@
 
 DECLARE_STACK_OF(SSL_CIPHER)
 
-typedef struct ssl_st SSL;
-typedef struct ssl_ctx_st SSL_CTX;
-
 /* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
 typedef struct ssl_method_st
 	{
@@ -760,6 +758,12 @@
 
 	int quiet_shutdown;
 
+#ifndef OPENSSL_ENGINE
+	/* Engine to pass requests for client certs to
+	 */
+	ENGINE *client_cert_engine;
+#endif
+
 #ifndef OPENSSL_NO_TLSEXT
 	/* TLS extensions servername callback */
 	int (*tlsext_servername_callback)(SSL*, int *, void *);
@@ -829,6 +833,9 @@
 void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val);
 void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
 int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+#ifndef OPENSSL_NO_ENGINE
+int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e);
+#endif
 void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len));
 void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len));
 
@@ -1702,6 +1709,7 @@
 #define SSL_F_SSL3_CONNECT				 132
 #define SSL_F_SSL3_CTRL					 213
 #define SSL_F_SSL3_CTX_CTRL				 133
+#define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC		 279
 #define SSL_F_SSL3_ENC					 134
 #define SSL_F_SSL3_GENERATE_KEY_BLOCK			 238
 #define SSL_F_SSL3_GET_CERTIFICATE_REQUEST		 135
@@ -1755,6 +1763,7 @@
 #define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY			 168
 #define SSL_F_SSL_CTX_NEW				 169
 #define SSL_F_SSL_CTX_SET_CIPHER_LIST			 269
+#define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE		 278
 #define SSL_F_SSL_CTX_SET_PURPOSE			 226
 #define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT		 219
 #define SSL_F_SSL_CTX_SET_SSL_VERSION			 170
@@ -1935,6 +1944,7 @@
 #define SSL_R_NO_CIPHERS_SPECIFIED			 183
 #define SSL_R_NO_CIPHER_LIST				 184
 #define SSL_R_NO_CIPHER_MATCH				 185
+#define SSL_R_NO_CLIENT_CERT_METHOD			 317
 #define SSL_R_NO_CLIENT_CERT_RECEIVED			 186
 #define SSL_R_NO_COMPRESSION_SPECIFIED			 187
 #define SSL_R_NO_METHOD_SPECIFIED			 188
diff --git a/include/openssl/symhacks.h b/include/openssl/symhacks.h
index 64528ad..8728e61 100644
--- a/include/openssl/symhacks.h
+++ b/include/openssl/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/include/openssl/x509v3.h b/include/openssl/x509v3.h
index db2b048..9ef83da 100644
--- a/include/openssl/x509v3.h
+++ b/include/openssl/x509v3.h
@@ -1,5 +1,5 @@
 /* x509v3.h */
-/* Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
+/* Written by Dr Stephen N Henson ([email protected]) 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
diff --git a/openssl.config b/openssl.config
new file mode 100644
index 0000000..977aa56
--- /dev/null
+++ b/openssl.config
@@ -0,0 +1,23 @@
+CONFIGURE_ARGS="\
+        linux-generic32 \
+        no-idea no-bf no-cast no-seed no-md2 \
+        -DL_ENDIAN"
+
+UNNEEDED_SOURCES="\
+        MacOS Netware VMS apps/demoCA apps/set bugs certs crypto/bf crypto/cast  \
+        crypto/cms crypto/idea crypto/md2 crypto/rc5 crypto/seed demos doc       \
+        engines ms os2 perl shlib test times tools util "
+
+UNNEEDED_SOURCES+="\
+        CHANGES CHANGES.SSLeay ChangeLog.0_9_7-stable_not-in-head                \
+        ChangeLog.0_9_7-stable_not-in-head_FIPS Configure FAQ INSTALL            \
+        INSTALL.DJGPP INSTALL.MacOS INSTALL.NW INSTALL.OS2 INSTALL.VMS           \
+        INSTALL.W32 INSTALL.W64 INSTALL.WCE LICENSE Makefile Makefile.bak        \
+        Makefile.org Makefile.shared NEWS PROBLEMS README README.ASN1            \
+        README.ENGINE apps/CA.pl.bak config crypto/opensslconf.h.bak             \
+        install.com makevms.com openssl.doxy openssl.spec"
+
+OPENSSL_PATCHES="\
+        progs.patch             \
+        arm-asm.patch           \
+	openssl_defs.patch"
diff --git a/openssl.version b/openssl.version
new file mode 100644
index 0000000..587f050
--- /dev/null
+++ b/openssl.version
@@ -0,0 +1 @@
+OPENSSL_VERSION=0.9.8k
diff --git a/patches/apps_Android.mk b/patches/apps_Android.mk
new file mode 100644
index 0000000..d4e701f
--- /dev/null
+++ b/patches/apps_Android.mk
@@ -0,0 +1,41 @@
+# Copyright 2006 The Android Open Source Project
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    openssl.c verify.c asn1pars.c req.c dgst.c dh.c enc.c passwd.c gendh.c errstr.c ca.c \
+    pkcs7.c crl2p7.c crl.c \
+    rsa.c rsautl.c dsa.c dsaparam.c ecparam.c \
+    x509.c genrsa.c gendsa.c s_client.c speed.c \
+    s_time.c  apps.c s_cb.c s_socket.c app_rand.c  version.c sess_id.c \
+    ciphers.c nseq.c pkcs12.c pkcs8.c spkac.c smime.c rand.c engine.c \
+    ocsp.c prime.c dhparam.c
+
+#   cms.c ec.c s_server.c
+
+LOCAL_SHARED_LIBRARIES := \
+	libssl \
+	libcrypto 
+
+LOCAL_C_INCLUDES := \
+	external/openssl \
+	external/openssl/include
+
+LOCAL_CFLAGS := -DMONOLITH
+
+LOCAL_CFLAGS += -DOPENSSL_NO_ECDH
+
+include $(LOCAL_PATH)/../android-config.mk
+
+
+# These flags omit whole features from the commandline "openssl".
+# However, portions of these features are actually turned on.
+LOCAL_CFLAGS += -DOPENSSL_NO_EC -DOPENSSL_NO_ECDSA -DOPENSSL_NO_DTLS1
+
+
+LOCAL_MODULE:= openssl
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_EXECUTABLE)
diff --git a/patches/arm-asm.patch b/patches/arm-asm.patch
new file mode 100644
index 0000000..9c8cb40
--- /dev/null
+++ b/patches/arm-asm.patch
@@ -0,0 +1,5106 @@
+--- /dev/null	2009-04-24 06:09:48.000000000 -0700
++++ openssl-0.9.8h/crypto/0.9.9-dev/README.android	2009-09-03 15:42:39.000000000 -0700
+@@ -0,0 +1,6 @@
++This directory does not exist in the OpenSSL distribution.
++
++It has been added to import assembler code from OpenSSL 0.9.9-dev
++(ftp://ftp.openssl.org/snapshot/).  The assembler files (.s) were
++generated by running the Perl files (.pl), with ".align 2" appended
++to avoid assembler error messages where needed.
+--- /dev/null	2009-04-24 06:09:48.000000000 -0700
++++ openssl-0.9.8h/crypto/0.9.9-dev/aes/aes-armv4.pl	2009-09-03 15:42:39.000000000 -0700
+@@ -0,0 +1,1030 @@
++#!/usr/bin/env perl
++
++# ====================================================================
++# Written by Andy Polyakov <[email protected]> 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;
+--- /dev/null	2009-04-24 06:09:48.000000000 -0700
++++ openssl-0.9.8h/crypto/0.9.9-dev/aes/aes-armv4.s	2009-09-03 15:42:39.000000000 -0700
+@@ -0,0 +1,982 @@
++.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	r12,r0		@ inp
++	mov	r11,r2
++	sub	r10,r3,#AES_encrypt-AES_Te	@ Te
++
++	ldrb	r0,[r12,#3]	@ load input data in endian-neutral
++	ldrb	r4,[r12,#2]	@ manner...
++	ldrb	r5,[r12,#1]
++	ldrb	r6,[r12,#0]
++	orr	r0,r0,r4,lsl#8
++	orr	r0,r0,r5,lsl#16
++	orr	r0,r0,r6,lsl#24
++	ldrb	r1,[r12,#7]
++	ldrb	r4,[r12,#6]
++	ldrb	r5,[r12,#5]
++	ldrb	r6,[r12,#4]
++	orr	r1,r1,r4,lsl#8
++	orr	r1,r1,r5,lsl#16
++	orr	r1,r1,r6,lsl#24
++	ldrb	r2,[r12,#11]
++	ldrb	r4,[r12,#10]
++	ldrb	r5,[r12,#9]
++	ldrb	r6,[r12,#8]
++	orr	r2,r2,r4,lsl#8
++	orr	r2,r2,r5,lsl#16
++	orr	r2,r2,r6,lsl#24
++	ldrb	r3,[r12,#15]
++	ldrb	r4,[r12,#14]
++	ldrb	r5,[r12,#13]
++	ldrb	r6,[r12,#12]
++	orr	r3,r3,r4,lsl#8
++	orr	r3,r3,r5,lsl#16
++	orr	r3,r3,r6,lsl#24
++
++	bl	_armv4_AES_encrypt
++
++	ldr	r12,[sp],#4		@ pop out
++	mov	r4,r0,lsr#24		@ write output in endian-neutral
++	mov	r5,r0,lsr#16		@ manner...
++	mov	r6,r0,lsr#8
++	strb	r4,[r12,#0]
++	strb	r5,[r12,#1]
++	strb	r6,[r12,#2]
++	strb	r0,[r12,#3]
++	mov	r4,r1,lsr#24
++	mov	r5,r1,lsr#16
++	mov	r6,r1,lsr#8
++	strb	r4,[r12,#4]
++	strb	r5,[r12,#5]
++	strb	r6,[r12,#6]
++	strb	r1,[r12,#7]
++	mov	r4,r2,lsr#24
++	mov	r5,r2,lsr#16
++	mov	r6,r2,lsr#8
++	strb	r4,[r12,#8]
++	strb	r5,[r12,#9]
++	strb	r6,[r12,#10]
++	strb	r2,[r12,#11]
++	mov	r4,r3,lsr#24
++	mov	r5,r3,lsr#16
++	mov	r6,r3,lsr#8
++	strb	r4,[r12,#12]
++	strb	r5,[r12,#13]
++	strb	r6,[r12,#14]
++	strb	r3,[r12,#15]
++
++	ldmia   sp!,{r4-r12,lr}
++	tst	lr,#1
++	moveq	pc,lr			@ be binary compatible with V4, yet
++	.word	0xe12fff1e			@ 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	r4,[r11],#16
++	ldr	r5,[r11,#-12]
++	ldr	r6,[r11,#-8]
++	ldr	r7,[r11,#-4]
++	ldr	r12,[r11,#240-16]
++	eor	r0,r0,r4
++	eor	r1,r1,r5
++	eor	r2,r2,r6
++	eor	r3,r3,r7
++	sub	r12,r12,#1
++	mov	lr,#255
++
++.Lenc_loop:
++	and	r8,lr,r0,lsr#8
++	and	r9,lr,r0,lsr#16
++	and	r7,lr,r0
++	mov	r0,r0,lsr#24
++	ldr	r4,[r10,r7,lsl#2]	@ Te3[s0>>0]
++	ldr	r0,[r10,r0,lsl#2]	@ Te0[s0>>24]
++	ldr	r5,[r10,r8,lsl#2]	@ Te2[s0>>8]
++	ldr	r6,[r10,r9,lsl#2]	@ Te1[s0>>16]
++
++	and	r7,lr,r1,lsr#16	@ i0
++	and	r8,lr,r1
++	and	r9,lr,r1,lsr#8
++	mov	r1,r1,lsr#24
++	ldr	r7,[r10,r7,lsl#2]	@ Te1[s1>>16]
++	ldr	r1,[r10,r1,lsl#2]	@ Te0[s1>>24]
++	ldr	r8,[r10,r8,lsl#2]	@ Te3[s1>>0]
++	ldr	r9,[r10,r9,lsl#2]	@ Te2[s1>>8]
++	eor	r0,r0,r7,ror#8
++	eor	r1,r1,r4,ror#24
++	eor	r5,r5,r8,ror#8
++	eor	r6,r6,r9,ror#8
++
++	and	r7,lr,r2,lsr#8	@ i0
++	and	r8,lr,r2,lsr#16	@ i1
++	and	r9,lr,r2
++	mov	r2,r2,lsr#24
++	ldr	r7,[r10,r7,lsl#2]	@ Te2[s2>>8]
++	ldr	r8,[r10,r8,lsl#2]	@ Te1[s2>>16]
++	ldr	r2,[r10,r2,lsl#2]	@ Te0[s2>>24]
++	ldr	r9,[r10,r9,lsl#2]	@ Te3[s2>>0]
++	eor	r0,r0,r7,ror#16
++	eor	r1,r1,r8,ror#8
++	eor	r2,r2,r5,ror#16
++	eor	r6,r6,r9,ror#16
++
++	and	r7,lr,r3		@ i0
++	and	r8,lr,r3,lsr#8	@ i1
++	and	r9,lr,r3,lsr#16	@ i2
++	mov	r3,r3,lsr#24
++	ldr	r7,[r10,r7,lsl#2]	@ Te3[s3>>0]
++	ldr	r8,[r10,r8,lsl#2]	@ Te2[s3>>8]
++	ldr	r9,[r10,r9,lsl#2]	@ Te1[s3>>16]
++	ldr	r3,[r10,r3,lsl#2]	@ Te0[s3>>24]
++	eor	r0,r0,r7,ror#24
++	eor	r1,r1,r8,ror#16
++	eor	r2,r2,r9,ror#8
++	eor	r3,r3,r6,ror#8
++
++	ldr	r4,[r11],#16
++	ldr	r5,[r11,#-12]
++	ldr	r6,[r11,#-8]
++	ldr	r7,[r11,#-4]
++	eor	r0,r0,r4
++	eor	r1,r1,r5
++	eor	r2,r2,r6
++	eor	r3,r3,r7
++
++	subs	r12,r12,#1
++	bne	.Lenc_loop
++
++	add	r10,r10,#2
++
++	and	r7,lr,r0
++	and	r8,lr,r0,lsr#8
++	and	r9,lr,r0,lsr#16
++	mov	r0,r0,lsr#24
++	ldrb	r4,[r10,r7,lsl#2]	@ Te4[s0>>0]
++	ldrb	r0,[r10,r0,lsl#2]	@ Te4[s0>>24]
++	ldrb	r5,[r10,r8,lsl#2]	@ Te4[s0>>8]
++	ldrb	r6,[r10,r9,lsl#2]	@ Te4[s0>>16]
++
++	and	r7,lr,r1,lsr#16	@ i0
++	and	r8,lr,r1
++	and	r9,lr,r1,lsr#8
++	mov	r1,r1,lsr#24
++	ldrb	r7,[r10,r7,lsl#2]	@ Te4[s1>>16]
++	ldrb	r1,[r10,r1,lsl#2]	@ Te4[s1>>24]
++	ldrb	r8,[r10,r8,lsl#2]	@ Te4[s1>>0]
++	ldrb	r9,[r10,r9,lsl#2]	@ Te4[s1>>8]
++	eor	r0,r7,r0,lsl#8
++	eor	r1,r4,r1,lsl#24
++	eor	r5,r8,r5,lsl#8
++	eor	r6,r9,r6,lsl#8
++
++	and	r7,lr,r2,lsr#8	@ i0
++	and	r8,lr,r2,lsr#16	@ i1
++	and	r9,lr,r2
++	mov	r2,r2,lsr#24
++	ldrb	r7,[r10,r7,lsl#2]	@ Te4[s2>>8]
++	ldrb	r8,[r10,r8,lsl#2]	@ Te4[s2>>16]
++	ldrb	r2,[r10,r2,lsl#2]	@ Te4[s2>>24]
++	ldrb	r9,[r10,r9,lsl#2]	@ Te4[s2>>0]
++	eor	r0,r7,r0,lsl#8
++	eor	r1,r1,r8,lsl#16
++	eor	r2,r5,r2,lsl#24
++	eor	r6,r9,r6,lsl#8
++
++	and	r7,lr,r3		@ i0
++	and	r8,lr,r3,lsr#8	@ i1
++	and	r9,lr,r3,lsr#16	@ i2
++	mov	r3,r3,lsr#24
++	ldrb	r7,[r10,r7,lsl#2]	@ Te4[s3>>0]
++	ldrb	r8,[r10,r8,lsl#2]	@ Te4[s3>>8]
++	ldrb	r9,[r10,r9,lsl#2]	@ Te4[s3>>16]
++	ldrb	r3,[r10,r3,lsl#2]	@ Te4[s3>>24]
++	eor	r0,r7,r0,lsl#8
++	eor	r1,r1,r8,lsl#8
++	eor	r2,r2,r9,lsl#16
++	eor	r3,r6,r3,lsl#24
++
++	ldr	lr,[sp],#4		@ pop lr
++	ldr	r4,[r11,#0]
++	ldr	r5,[r11,#4]
++	ldr	r6,[r11,#8]
++	ldr	r7,[r11,#12]
++	eor	r0,r0,r4
++	eor	r1,r1,r5
++	eor	r2,r2,r6
++	eor	r3,r3,r7
++
++	sub	r10,r10,#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	r10,r3,#AES_set_encrypt_key-AES_Te-1024	@ Te4
++
++	mov	r12,r0		@ inp
++	mov	lr,r1			@ bits
++	mov	r11,r2			@ key
++
++	ldrb	r0,[r12,#3]	@ load input data in endian-neutral
++	ldrb	r4,[r12,#2]	@ manner...
++	ldrb	r5,[r12,#1]
++	ldrb	r6,[r12,#0]
++	orr	r0,r0,r4,lsl#8
++	orr	r0,r0,r5,lsl#16
++	orr	r0,r0,r6,lsl#24
++	ldrb	r1,[r12,#7]
++	ldrb	r4,[r12,#6]
++	ldrb	r5,[r12,#5]
++	ldrb	r6,[r12,#4]
++	orr	r1,r1,r4,lsl#8
++	orr	r1,r1,r5,lsl#16
++	orr	r1,r1,r6,lsl#24
++	ldrb	r2,[r12,#11]
++	ldrb	r4,[r12,#10]
++	ldrb	r5,[r12,#9]
++	ldrb	r6,[r12,#8]
++	orr	r2,r2,r4,lsl#8
++	orr	r2,r2,r5,lsl#16
++	orr	r2,r2,r6,lsl#24
++	ldrb	r3,[r12,#15]
++	ldrb	r4,[r12,#14]
++	ldrb	r5,[r12,#13]
++	ldrb	r6,[r12,#12]
++	orr	r3,r3,r4,lsl#8
++	orr	r3,r3,r5,lsl#16
++	orr	r3,r3,r6,lsl#24
++	str	r0,[r11],#16
++	str	r1,[r11,#-12]
++	str	r2,[r11,#-8]
++	str	r3,[r11,#-4]
++
++	teq	lr,#128
++	bne	.Lnot128
++	mov	r12,#10
++	str	r12,[r11,#240-16]
++	add	r6,r10,#256			@ rcon
++	mov	lr,#255
++
++.L128_loop:
++	and	r5,lr,r3,lsr#24
++	and	r7,lr,r3,lsr#16
++	and	r8,lr,r3,lsr#8
++	and	r9,lr,r3
++	ldrb	r5,[r10,r5]
++	ldrb	r7,[r10,r7]
++	ldrb	r8,[r10,r8]
++	ldrb	r9,[r10,r9]
++	ldr	r4,[r6],#4			@ rcon[i++]
++	orr	r5,r5,r7,lsl#24
++	orr	r5,r5,r8,lsl#16
++	orr	r5,r5,r9,lsl#8
++	eor	r5,r5,r4
++	eor	r0,r0,r5			@ rk[4]=rk[0]^...
++	eor	r1,r1,r0			@ rk[5]=rk[1]^rk[4]
++	eor	r2,r2,r1			@ rk[6]=rk[2]^rk[5]
++	eor	r3,r3,r2			@ rk[7]=rk[3]^rk[6]
++	str	r0,[r11],#16
++	str	r1,[r11,#-12]
++	str	r2,[r11,#-8]
++	str	r3,[r11,#-4]
++
++	subs	r12,r12,#1
++	bne	.L128_loop
++	sub	r2,r11,#176
++	b	.Ldone
++
++.Lnot128:
++	ldrb	r8,[r12,#19]
++	ldrb	r4,[r12,#18]
++	ldrb	r5,[r12,#17]
++	ldrb	r6,[r12,#16]
++	orr	r8,r8,r4,lsl#8
++	orr	r8,r8,r5,lsl#16
++	orr	r8,r8,r6,lsl#24
++	ldrb	r9,[r12,#23]
++	ldrb	r4,[r12,#22]
++	ldrb	r5,[r12,#21]
++	ldrb	r6,[r12,#20]
++	orr	r9,r9,r4,lsl#8
++	orr	r9,r9,r5,lsl#16
++	orr	r9,r9,r6,lsl#24
++	str	r8,[r11],#8
++	str	r9,[r11,#-4]
++
++	teq	lr,#192
++	bne	.Lnot192
++	mov	r12,#12
++	str	r12,[r11,#240-24]
++	add	r6,r10,#256			@ rcon
++	mov	lr,#255
++	mov	r12,#8
++
++.L192_loop:
++	and	r5,lr,r9,lsr#24
++	and	r7,lr,r9,lsr#16
++	and	r8,lr,r9,lsr#8
++	and	r9,lr,r9
++	ldrb	r5,[r10,r5]
++	ldrb	r7,[r10,r7]
++	ldrb	r8,[r10,r8]
++	ldrb	r9,[r10,r9]
++	ldr	r4,[r6],#4			@ rcon[i++]
++	orr	r5,r5,r7,lsl#24
++	orr	r5,r5,r8,lsl#16
++	orr	r5,r5,r9,lsl#8
++	eor	r9,r5,r4
++	eor	r0,r0,r9			@ rk[6]=rk[0]^...
++	eor	r1,r1,r0			@ rk[7]=rk[1]^rk[6]
++	eor	r2,r2,r1			@ rk[8]=rk[2]^rk[7]
++	eor	r3,r3,r2			@ rk[9]=rk[3]^rk[8]
++	str	r0,[r11],#24
++	str	r1,[r11,#-20]
++	str	r2,[r11,#-16]
++	str	r3,[r11,#-12]
++
++	subs	r12,r12,#1
++	subeq	r2,r11,#216
++	beq	.Ldone
++
++	ldr	r7,[r11,#-32]
++	ldr	r8,[r11,#-28]
++	eor	r7,r7,r3			@ rk[10]=rk[4]^rk[9]
++	eor	r9,r8,r7			@ rk[11]=rk[5]^rk[10]
++	str	r7,[r11,#-8]
++	str	r9,[r11,#-4]
++	b	.L192_loop
++
++.Lnot192:
++	ldrb	r8,[r12,#27]
++	ldrb	r4,[r12,#26]
++	ldrb	r5,[r12,#25]
++	ldrb	r6,[r12,#24]
++	orr	r8,r8,r4,lsl#8
++	orr	r8,r8,r5,lsl#16
++	orr	r8,r8,r6,lsl#24
++	ldrb	r9,[r12,#31]
++	ldrb	r4,[r12,#30]
++	ldrb	r5,[r12,#29]
++	ldrb	r6,[r12,#28]
++	orr	r9,r9,r4,lsl#8
++	orr	r9,r9,r5,lsl#16
++	orr	r9,r9,r6,lsl#24
++	str	r8,[r11],#8
++	str	r9,[r11,#-4]
++
++	mov	r12,#14
++	str	r12,[r11,#240-32]
++	add	r6,r10,#256			@ rcon
++	mov	lr,#255
++	mov	r12,#7
++
++.L256_loop:
++	and	r5,lr,r9,lsr#24
++	and	r7,lr,r9,lsr#16
++	and	r8,lr,r9,lsr#8
++	and	r9,lr,r9
++	ldrb	r5,[r10,r5]
++	ldrb	r7,[r10,r7]
++	ldrb	r8,[r10,r8]
++	ldrb	r9,[r10,r9]
++	ldr	r4,[r6],#4			@ rcon[i++]
++	orr	r5,r5,r7,lsl#24
++	orr	r5,r5,r8,lsl#16
++	orr	r5,r5,r9,lsl#8
++	eor	r9,r5,r4
++	eor	r0,r0,r9			@ rk[8]=rk[0]^...
++	eor	r1,r1,r0			@ rk[9]=rk[1]^rk[8]
++	eor	r2,r2,r1			@ rk[10]=rk[2]^rk[9]
++	eor	r3,r3,r2			@ rk[11]=rk[3]^rk[10]
++	str	r0,[r11],#32
++	str	r1,[r11,#-28]
++	str	r2,[r11,#-24]
++	str	r3,[r11,#-20]
++
++	subs	r12,r12,#1
++	subeq	r2,r11,#256
++	beq	.Ldone
++
++	and	r5,lr,r3
++	and	r7,lr,r3,lsr#8
++	and	r8,lr,r3,lsr#16
++	and	r9,lr,r3,lsr#24
++	ldrb	r5,[r10,r5]
++	ldrb	r7,[r10,r7]
++	ldrb	r8,[r10,r8]
++	ldrb	r9,[r10,r9]
++	orr	r5,r5,r7,lsl#8
++	orr	r5,r5,r8,lsl#16
++	orr	r5,r5,r9,lsl#24
++
++	ldr	r4,[r11,#-48]
++	ldr	r7,[r11,#-44]
++	ldr	r8,[r11,#-40]
++	ldr	r9,[r11,#-36]
++	eor	r4,r4,r5			@ rk[12]=rk[4]^...
++	eor	r7,r7,r4			@ rk[13]=rk[5]^rk[12]
++	eor	r8,r8,r7			@ rk[14]=rk[6]^rk[13]
++	eor	r9,r9,r8			@ rk[15]=rk[7]^rk[14]
++	str	r4,[r11,#-16]
++	str	r7,[r11,#-12]
++	str	r8,[r11,#-8]
++	str	r9,[r11,#-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
++	.word	0xe12fff1e			@ 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	r12,[r2,#240]	@ AES_set_encrypt_key preserves r2,
++	mov	r11,r2			@ which is AES_KEY *key
++	mov	r7,r2
++	add	r8,r2,r12,lsl#4
++
++.Linv:	ldr	r0,[r7]
++	ldr	r1,[r7,#4]
++	ldr	r2,[r7,#8]
++	ldr	r3,[r7,#12]
++	ldr	r4,[r8]
++	ldr	r5,[r8,#4]
++	ldr	r6,[r8,#8]
++	ldr	r9,[r8,#12]
++	str	r0,[r8],#-16
++	str	r1,[r8,#16+4]
++	str	r2,[r8,#16+8]
++	str	r3,[r8,#16+12]
++	str	r4,[r7],#16
++	str	r5,[r7,#-12]
++	str	r6,[r7,#-8]
++	str	r9,[r7,#-4]
++	teq	r7,r8
++	bne	.Linv
++	ldr	r0,[r11,#16]!		@ prefetch tp1
++	mov	r7,#0x80
++	mov	r8,#0x1b
++	orr	r7,r7,#0x8000
++	orr	r8,r8,#0x1b00
++	orr	r7,r7,r7,lsl#16
++	orr	r8,r8,r8,lsl#16
++	sub	r12,r12,#1
++	mvn	r9,r7
++	mov	r12,r12,lsl#2	@ (rounds-1)*4
++
++.Lmix:	and	r4,r0,r7
++	and	r1,r0,r9
++	sub	r4,r4,r4,lsr#7
++	and	r4,r4,r8
++	eor	r1,r4,r1,lsl#1	@ tp2
++
++	and	r4,r1,r7
++	and	r2,r1,r9
++	sub	r4,r4,r4,lsr#7
++	and	r4,r4,r8
++	eor	r2,r4,r2,lsl#1	@ tp4
++
++	and	r4,r2,r7
++	and	r3,r2,r9
++	sub	r4,r4,r4,lsr#7
++	and	r4,r4,r8
++	eor	r3,r4,r3,lsl#1	@ tp8
++
++	eor	r4,r1,r2
++	eor	r5,r0,r3		@ tp9
++	eor	r4,r4,r3		@ tpe
++	eor	r4,r4,r1,ror#24
++	eor	r4,r4,r5,ror#24	@ ^= ROTATE(tpb=tp9^tp2,8)
++	eor	r4,r4,r2,ror#16
++	eor	r4,r4,r5,ror#16	@ ^= ROTATE(tpd=tp9^tp4,16)
++	eor	r4,r4,r5,ror#8	@ ^= ROTATE(tp9,24)
++
++	ldr	r0,[r11,#4]		@ prefetch tp1
++	str	r4,[r11],#4
++	subs	r12,r12,#1
++	bne	.Lmix
++
++	mov	r0,#0
++	ldmia   sp!,{r4-r12,lr}
++	tst	lr,#1
++	moveq	pc,lr			@ be binary compatible with V4, yet
++	.word	0xe12fff1e			@ 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	r12,r0		@ inp
++	mov	r11,r2
++	sub	r10,r3,#AES_decrypt-AES_Td		@ Td
++
++	ldrb	r0,[r12,#3]	@ load input data in endian-neutral
++	ldrb	r4,[r12,#2]	@ manner...
++	ldrb	r5,[r12,#1]
++	ldrb	r6,[r12,#0]
++	orr	r0,r0,r4,lsl#8
++	orr	r0,r0,r5,lsl#16
++	orr	r0,r0,r6,lsl#24
++	ldrb	r1,[r12,#7]
++	ldrb	r4,[r12,#6]
++	ldrb	r5,[r12,#5]
++	ldrb	r6,[r12,#4]
++	orr	r1,r1,r4,lsl#8
++	orr	r1,r1,r5,lsl#16
++	orr	r1,r1,r6,lsl#24
++	ldrb	r2,[r12,#11]
++	ldrb	r4,[r12,#10]
++	ldrb	r5,[r12,#9]
++	ldrb	r6,[r12,#8]
++	orr	r2,r2,r4,lsl#8
++	orr	r2,r2,r5,lsl#16
++	orr	r2,r2,r6,lsl#24
++	ldrb	r3,[r12,#15]
++	ldrb	r4,[r12,#14]
++	ldrb	r5,[r12,#13]
++	ldrb	r6,[r12,#12]
++	orr	r3,r3,r4,lsl#8
++	orr	r3,r3,r5,lsl#16
++	orr	r3,r3,r6,lsl#24
++
++	bl	_armv4_AES_decrypt
++
++	ldr	r12,[sp],#4		@ pop out
++	mov	r4,r0,lsr#24		@ write output in endian-neutral
++	mov	r5,r0,lsr#16		@ manner...
++	mov	r6,r0,lsr#8
++	strb	r4,[r12,#0]
++	strb	r5,[r12,#1]
++	strb	r6,[r12,#2]
++	strb	r0,[r12,#3]
++	mov	r4,r1,lsr#24
++	mov	r5,r1,lsr#16
++	mov	r6,r1,lsr#8
++	strb	r4,[r12,#4]
++	strb	r5,[r12,#5]
++	strb	r6,[r12,#6]
++	strb	r1,[r12,#7]
++	mov	r4,r2,lsr#24
++	mov	r5,r2,lsr#16
++	mov	r6,r2,lsr#8
++	strb	r4,[r12,#8]
++	strb	r5,[r12,#9]
++	strb	r6,[r12,#10]
++	strb	r2,[r12,#11]
++	mov	r4,r3,lsr#24
++	mov	r5,r3,lsr#16
++	mov	r6,r3,lsr#8
++	strb	r4,[r12,#12]
++	strb	r5,[r12,#13]
++	strb	r6,[r12,#14]
++	strb	r3,[r12,#15]
++
++	ldmia   sp!,{r4-r12,lr}
++	tst	lr,#1
++	moveq	pc,lr			@ be binary compatible with V4, yet
++	.word	0xe12fff1e			@ 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	r4,[r11],#16
++	ldr	r5,[r11,#-12]
++	ldr	r6,[r11,#-8]
++	ldr	r7,[r11,#-4]
++	ldr	r12,[r11,#240-16]
++	eor	r0,r0,r4
++	eor	r1,r1,r5
++	eor	r2,r2,r6
++	eor	r3,r3,r7
++	sub	r12,r12,#1
++	mov	lr,#255
++
++.Ldec_loop:
++	and	r7,lr,r0,lsr#16
++	and	r8,lr,r0,lsr#8
++	and	r9,lr,r0
++	mov	r0,r0,lsr#24
++	ldr	r4,[r10,r7,lsl#2]	@ Td1[s0>>16]
++	ldr	r0,[r10,r0,lsl#2]	@ Td0[s0>>24]
++	ldr	r5,[r10,r8,lsl#2]	@ Td2[s0>>8]
++	ldr	r6,[r10,r9,lsl#2]	@ Td3[s0>>0]
++
++	and	r7,lr,r1		@ i0
++	and	r8,lr,r1,lsr#16
++	and	r9,lr,r1,lsr#8
++	mov	r1,r1,lsr#24
++	ldr	r7,[r10,r7,lsl#2]	@ Td3[s1>>0]
++	ldr	r1,[r10,r1,lsl#2]	@ Td0[s1>>24]
++	ldr	r8,[r10,r8,lsl#2]	@ Td1[s1>>16]
++	ldr	r9,[r10,r9,lsl#2]	@ Td2[s1>>8]
++	eor	r0,r0,r7,ror#24
++	eor	r1,r1,r4,ror#8
++	eor	r5,r8,r5,ror#8
++	eor	r6,r9,r6,ror#8
++
++	and	r7,lr,r2,lsr#8	@ i0
++	and	r8,lr,r2		@ i1
++	and	r9,lr,r2,lsr#16
++	mov	r2,r2,lsr#24
++	ldr	r7,[r10,r7,lsl#2]	@ Td2[s2>>8]
++	ldr	r8,[r10,r8,lsl#2]	@ Td3[s2>>0]
++	ldr	r2,[r10,r2,lsl#2]	@ Td0[s2>>24]
++	ldr	r9,[r10,r9,lsl#2]	@ Td1[s2>>16]
++	eor	r0,r0,r7,ror#16
++	eor	r1,r1,r8,ror#24
++	eor	r2,r2,r5,ror#8
++	eor	r6,r9,r6,ror#8
++
++	and	r7,lr,r3,lsr#16	@ i0
++	and	r8,lr,r3,lsr#8	@ i1
++	and	r9,lr,r3		@ i2
++	mov	r3,r3,lsr#24
++	ldr	r7,[r10,r7,lsl#2]	@ Td1[s3>>16]
++	ldr	r8,[r10,r8,lsl#2]	@ Td2[s3>>8]
++	ldr	r9,[r10,r9,lsl#2]	@ Td3[s3>>0]
++	ldr	r3,[r10,r3,lsl#2]	@ Td0[s3>>24]
++	eor	r0,r0,r7,ror#8
++	eor	r1,r1,r8,ror#16
++	eor	r2,r2,r9,ror#24
++	eor	r3,r3,r6,ror#8
++
++	ldr	r4,[r11],#16
++	ldr	r5,[r11,#-12]
++	ldr	r6,[r11,#-8]
++	ldr	r7,[r11,#-4]
++	eor	r0,r0,r4
++	eor	r1,r1,r5
++	eor	r2,r2,r6
++	eor	r3,r3,r7
++
++	subs	r12,r12,#1
++	bne	.Ldec_loop
++
++	add	r10,r10,#1024
++
++	ldr	r4,[r10,#0]		@ prefetch Td4
++	ldr	r5,[r10,#32]
++	ldr	r6,[r10,#64]
++	ldr	r7,[r10,#96]
++	ldr	r8,[r10,#128]
++	ldr	r9,[r10,#160]
++	ldr	r4,[r10,#192]
++	ldr	r5,[r10,#224]
++
++	and	r7,lr,r0,lsr#16
++	and	r8,lr,r0,lsr#8
++	and	r9,lr,r0
++	ldrb	r0,[r10,r0,lsr#24]	@ Td4[s0>>24]
++	ldrb	r4,[r10,r7]		@ Td4[s0>>16]
++	ldrb	r5,[r10,r8]		@ Td4[s0>>8]
++	ldrb	r6,[r10,r9]		@ Td4[s0>>0]
++
++	and	r7,lr,r1		@ i0
++	and	r8,lr,r1,lsr#16
++	and	r9,lr,r1,lsr#8
++	ldrb	r7,[r10,r7]		@ Td4[s1>>0]
++	ldrb	r1,[r10,r1,lsr#24]	@ Td4[s1>>24]
++	ldrb	r8,[r10,r8]		@ Td4[s1>>16]
++	ldrb	r9,[r10,r9]		@ Td4[s1>>8]
++	eor	r0,r7,r0,lsl#24
++	eor	r1,r4,r1,lsl#8
++	eor	r5,r5,r8,lsl#8
++	eor	r6,r6,r9,lsl#8
++
++	and	r7,lr,r2,lsr#8	@ i0
++	and	r8,lr,r2		@ i1
++	and	r9,lr,r2,lsr#16
++	ldrb	r7,[r10,r7]		@ Td4[s2>>8]
++	ldrb	r8,[r10,r8]		@ Td4[s2>>0]
++	ldrb	r2,[r10,r2,lsr#24]	@ Td4[s2>>24]
++	ldrb	r9,[r10,r9]		@ Td4[s2>>16]
++	eor	r0,r0,r7,lsl#8
++	eor	r1,r8,r1,lsl#16
++	eor	r2,r5,r2,lsl#16
++	eor	r6,r6,r9,lsl#16
++
++	and	r7,lr,r3,lsr#16	@ i0
++	and	r8,lr,r3,lsr#8	@ i1
++	and	r9,lr,r3		@ i2
++	ldrb	r7,[r10,r7]		@ Td4[s3>>16]
++	ldrb	r8,[r10,r8]		@ Td4[s3>>8]
++	ldrb	r9,[r10,r9]		@ Td4[s3>>0]
++	ldrb	r3,[r10,r3,lsr#24]	@ Td4[s3>>24]
++	eor	r0,r0,r7,lsl#16
++	eor	r1,r1,r8,lsl#8
++	eor	r2,r9,r2,lsl#8
++	eor	r3,r6,r3,lsl#24
++
++	ldr	lr,[sp],#4		@ pop lr
++	ldr	r4,[r11,#0]
++	ldr	r5,[r11,#4]
++	ldr	r6,[r11,#8]
++	ldr	r7,[r11,#12]
++	eor	r0,r0,r4
++	eor	r1,r1,r5
++	eor	r2,r2,r6
++	eor	r3,r3,r7
++
++	sub	r10,r10,#1024
++	mov	pc,lr			@ return
++.size	_armv4_AES_decrypt,.-_armv4_AES_decrypt
++.asciz	"AES for ARMv4, CRYPTOGAMS by <[email protected]>"
++.align	2
+--- /dev/null	2009-04-24 06:09:48.000000000 -0700
++++ openssl-0.9.8h/crypto/0.9.9-dev/bn/armv4-mont.pl	2009-09-03 15:42:39.000000000 -0700
+@@ -0,0 +1,200 @@
++#!/usr/bin/env perl
++
++# ====================================================================
++# Written by Andy Polyakov <[email protected]> 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;
+--- /dev/null	2009-04-24 06:09:48.000000000 -0700
++++ openssl-0.9.8h/crypto/0.9.9-dev/bn/armv4-mont.s	2009-09-03 15:42:39.000000000 -0700
+@@ -0,0 +1,145 @@
++.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	r0,[sp,#3*4]		@ load num
++	cmp	r0,#2
++	movlt	r0,#0
++	addlt	sp,sp,#2*4
++	blt	.Labrt
++
++	stmdb	sp!,{r4-r12,lr}		@ save 10 registers
++
++	mov	r0,r0,lsl#2		@ rescale r0 for byte count
++	sub	sp,sp,r0		@ alloca(4*num)
++	sub	sp,sp,#4		@ +extra dword
++	sub	r0,r0,#4		@ "num=num-1"
++	add	r4,r2,r0		@ &bp[num-1]
++
++	add	r0,sp,r0		@ r0 to point at &tp[num-1]
++	ldr	r8,[r0,#14*4]		@ &n0
++	ldr	r2,[r2]		@ bp[0]
++	ldr	r5,[r1],#4		@ ap[0],ap++
++	ldr	r6,[r3],#4		@ np[0],np++
++	ldr	r8,[r8]		@ *n0
++	str	r4,[r0,#15*4]		@ save &bp[num]
++
++	umull	r10,r11,r5,r2	@ ap[0]*bp[0]
++	str	r8,[r0,#14*4]		@ save n0 value
++	mul	r8,r10,r8		@ "tp[0]"*n0
++	mov	r12,#0
++	umlal	r10,r12,r6,r8	@ np[0]*n0+"t[0]"
++	mov	r4,sp
++
++.L1st:
++	ldr	r5,[r1],#4		@ ap[j],ap++
++	mov	r10,r11
++	mov	r11,#0
++	umlal	r10,r11,r5,r2	@ ap[j]*bp[0]
++	ldr	r6,[r3],#4		@ np[j],np++
++	mov	r14,#0
++	umlal	r12,r14,r6,r8	@ np[j]*n0
++	adds	r12,r12,r10
++	str	r12,[r4],#4		@ tp[j-1]=,tp++
++	adc	r12,r14,#0
++	cmp	r4,r0
++	bne	.L1st
++
++	adds	r12,r12,r11
++	mov	r14,#0
++	adc	r14,r14,#0
++	ldr	r4,[r0,#13*4]		@ restore bp
++	str	r12,[r0]		@ tp[num-1]=
++	ldr	r8,[r0,#14*4]		@ restore n0
++	str	r14,[r0,#4]		@ tp[num]=
++
++.Louter:
++	sub	r7,r0,sp		@ "original" r0-1 value
++	sub	r1,r1,r7		@ "rewind" ap to &ap[1]
++	sub	r3,r3,r7		@ "rewind" np to &np[1]
++	ldr	r2,[r4,#4]!		@ *(++bp)
++	ldr	r5,[r1,#-4]		@ ap[0]
++	ldr	r6,[r3,#-4]		@ np[0]
++	ldr	r10,[sp]		@ tp[0]
++	ldr	r7,[sp,#4]		@ tp[1]
++
++	mov	r11,#0
++	umlal	r10,r11,r5,r2	@ ap[0]*bp[i]+tp[0]
++	str	r4,[r0,#13*4]		@ save bp
++	mul	r8,r10,r8
++	mov	r12,#0
++	umlal	r10,r12,r6,r8	@ np[0]*n0+"tp[0]"
++	mov	r4,sp
++
++.Linner:
++	ldr	r5,[r1],#4		@ ap[j],ap++
++	adds	r10,r11,r7		@ +=tp[j]
++	mov	r11,#0
++	umlal	r10,r11,r5,r2	@ ap[j]*bp[i]
++	ldr	r6,[r3],#4		@ np[j],np++
++	mov	r14,#0
++	umlal	r12,r14,r6,r8	@ np[j]*n0
++	ldr	r7,[r4,#8]		@ tp[j+1]
++	adc	r11,r11,#0
++	adds	r12,r12,r10
++	str	r12,[r4],#4		@ tp[j-1]=,tp++
++	adc	r12,r14,#0
++	cmp	r4,r0
++	bne	.Linner
++
++	adds	r12,r12,r11
++	mov	r14,#0
++	adc	r14,r14,#0
++	adds	r12,r12,r7
++	adc	r14,r14,#0
++	ldr	r4,[r0,#13*4]		@ restore bp
++	ldr	r7,[r0,#15*4]		@ restore &bp[num]
++	str	r12,[r0]		@ tp[num-1]=
++	ldr	r8,[r0,#14*4]		@ restore n0
++	str	r14,[r0,#4]		@ tp[num]=
++
++	cmp	r4,r7
++	bne	.Louter
++
++	ldr	r2,[r0,#12*4]		@ pull rp
++	add	r0,r0,#4		@ r0 to point at &tp[num]
++	sub	r5,r0,sp		@ "original" num value
++	mov	r4,sp			@ "rewind" r4
++	mov	r1,r4			@ "borrow" r1
++	sub	r3,r3,r5		@ "rewind" r3 to &np[0]
++
++	subs	r7,r7,r7		@ "clear" carry flag
++.Lsub:	ldr	r7,[r4],#4
++	ldr	r6,[r3],#4
++	sbcs	r7,r7,r6		@ tp[j]-np[j]
++	str	r7,[r2],#4		@ rp[j]=
++	teq	r4,r0		@ preserve carry
++	bne	.Lsub
++	sbcs	r14,r14,#0		@ upmost carry
++	mov	r4,sp			@ "rewind" r4
++	sub	r2,r2,r5		@ "rewind" r2
++
++	and	r1,r4,r14
++	bic	r3,r2,r14
++	orr	r1,r1,r3		@ ap=borrow?tp:rp
++
++.Lcopy:	ldr	r7,[r1],#4		@ copy or in-place refresh
++	str	sp,[r4],#4		@ zap tp
++	str	r7,[r2],#4
++	cmp	r4,r0
++	bne	.Lcopy
++
++	add	sp,r0,#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
++	.word	0xe12fff1e			@ interoperable with Thumb ISA:-)
++.size	bn_mul_mont,.-bn_mul_mont
++.asciz	"Montgomery multiplication for ARMv4, CRYPTOGAMS by <[email protected]>"
++.align	2
+--- /dev/null	2009-04-24 06:09:48.000000000 -0700
++++ openssl-0.9.8h/crypto/0.9.9-dev/sha/sha1-armv4-large.pl	2009-09-03 15:42:39.000000000 -0700
+@@ -0,0 +1,231 @@
++#!/usr/bin/env perl
++
++# ====================================================================
++# Written by Andy Polyakov <[email protected]> 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/.
++# ====================================================================
++
++# sha1_block procedure for ARMv4.
++#
++# January 2007.
++
++# Size/performance trade-off
++# ====================================================================
++# impl		size in bytes	comp cycles[*]	measured performance
++# ====================================================================
++# thumb		304		3212		4420
++# armv4-small	392/+29%	1958/+64%	2250/+96%
++# armv4-compact	740/+89%	1552/+26%	1840/+22%
++# armv4-large	1420/+92%	1307/+19%	1500/+23%
++# full unroll	~5100/+260%	~1260/+4%	~1500/+0%
++# ====================================================================
++# thumb		= same as 'small' but in Thumb instructions[**] and
++#		  with recurring code in two private functions;
++# small		= detached Xload/update, loops are folded;
++# compact	= detached Xload/update, 5x unroll;
++# large		= interleaved Xload/update, 5x unroll;
++# full unroll	= interleaved Xload/update, full unroll, estimated[!];
++#
++# [*]	Manually counted instructions in "grand" loop body. Measured
++#	performance is affected by prologue and epilogue overhead,
++#	i-cache availability, branch penalties, etc.
++# [**]	While each Thumb instruction is twice smaller, they are not as
++#	diverse as ARM ones: e.g., there are only two arithmetic
++#	instructions with 3 arguments, no [fixed] rotate, addressing
++#	modes are limited. As result it takes more instructions to do
++#	the same job in Thumb, therefore the code is never twice as
++#	small and always slower.
++
++$output=shift;
++open STDOUT,">$output";
++
++$ctx="r0";
++$inp="r1";
++$len="r2";
++$a="r3";
++$b="r4";
++$c="r5";
++$d="r6";
++$e="r7";
++$K="r8";
++$t0="r10";
++$t1="r11";
++$t2="r12";
++$Xi="r14";
++@V=($a,$b,$c,$d,$e);
++
++# One can optimize this for aligned access on big-endian architecture,
++# but code's endian neutrality makes it too pretty:-)
++sub Xload {
++my ($a,$b,$c,$d,$e)=@_;
++$code.=<<___;
++	ldrb	$t0,[$inp],#4
++	ldrb	$t1,[$inp,#-3]
++	ldrb	$t2,[$inp,#-2]
++	add	$e,$K,$e,ror#2			@ E+=K_00_19
++	orr	$t0,$t1,$t0,lsl#8
++	ldrb	$t1,[$inp,#-1]
++	orr	$t0,$t2,$t0,lsl#8
++	add	$e,$e,$a,ror#27			@ E+=ROR(A,27)
++	orr	$t0,$t1,$t0,lsl#8
++	add	$e,$e,$t0			@ E+=X[i]
++	eor	$t1,$c,$d			@ F_xx_xx
++	str	$t0,[$Xi,#-4]!
++___
++}
++sub Xupdate {
++my ($a,$b,$c,$d,$e,$flag)=@_;
++$code.=<<___;
++	ldr	$t0,[$Xi,#15*4]
++	ldr	$t1,[$Xi,#13*4]
++	ldr	$t2,[$Xi,#7*4]
++	add	$e,$K,$e,ror#2			@ E+=K_xx_xx
++	eor	$t0,$t0,$t1
++	ldr	$t1,[$Xi,#2*4]
++	add	$e,$e,$a,ror#27			@ E+=ROR(A,27)
++	eor	$t0,$t0,$t2
++	eor	$t0,$t0,$t1
++___
++$code.=<<___ if (!defined($flag));
++	eor	$t1,$c,$d			@ F_xx_xx, but not in 40_59
++___
++$code.=<<___;
++	mov	$t0,$t0,ror#31
++	add	$e,$e,$t0			@ E+=X[i]
++	str	$t0,[$Xi,#-4]!
++___
++}
++
++sub BODY_00_15 {
++my ($a,$b,$c,$d,$e)=@_;
++	&Xload(@_);
++$code.=<<___;
++	and	$t1,$b,$t1,ror#2
++	eor	$t1,$t1,$d,ror#2		@ F_00_19(B,C,D)
++	add	$e,$e,$t1			@ E+=F_00_19(B,C,D)
++___
++}
++
++sub BODY_16_19 {
++my ($a,$b,$c,$d,$e)=@_;
++	&Xupdate(@_);
++$code.=<<___;
++	and	$t1,$b,$t1,ror#2
++	eor	$t1,$t1,$d,ror#2		@ F_00_19(B,C,D)
++	add	$e,$e,$t1			@ E+=F_00_19(B,C,D)
++___
++}
++
++sub BODY_20_39 {
++my ($a,$b,$c,$d,$e)=@_;
++	&Xupdate(@_);
++$code.=<<___;
++	eor	$t1,$b,$t1,ror#2		@ F_20_39(B,C,D)
++	add	$e,$e,$t1			@ E+=F_20_39(B,C,D)
++___
++}
++
++sub BODY_40_59 {
++my ($a,$b,$c,$d,$e)=@_;
++	&Xupdate(@_,1);
++$code.=<<___;
++	and	$t1,$b,$c,ror#2
++	orr	$t2,$b,$c,ror#2
++	and	$t2,$t2,$d,ror#2
++	orr	$t1,$t1,$t2			@ F_40_59(B,C,D)
++	add	$e,$e,$t1			@ E+=F_40_59(B,C,D)
++___
++}
++
++$code=<<___;
++.text
++
++.global	sha1_block_data_order
++.type	sha1_block_data_order,%function
++
++.align	2
++sha1_block_data_order:
++	stmdb	sp!,{r4-r12,lr}
++	add	$len,$inp,$len,lsl#6	@ $len to point at the end of $inp
++	ldmia	$ctx,{$a,$b,$c,$d,$e}
++.Lloop:
++	ldr	$K,.LK_00_19
++	mov	$Xi,sp
++	sub	sp,sp,#15*4
++	mov	$c,$c,ror#30
++	mov	$d,$d,ror#30
++	mov	$e,$e,ror#30		@ [6]
++.L_00_15:
++___
++for($i=0;$i<5;$i++) {
++	&BODY_00_15(@V);	unshift(@V,pop(@V));
++}
++$code.=<<___;
++	teq	$Xi,sp
++	bne	.L_00_15		@ [((11+4)*5+2)*3]
++___
++	&BODY_00_15(@V);	unshift(@V,pop(@V));
++	&BODY_16_19(@V);	unshift(@V,pop(@V));
++	&BODY_16_19(@V);	unshift(@V,pop(@V));
++	&BODY_16_19(@V);	unshift(@V,pop(@V));
++	&BODY_16_19(@V);	unshift(@V,pop(@V));
++$code.=<<___;
++
++	ldr	$K,.LK_20_39		@ [+15+16*4]
++	sub	sp,sp,#25*4
++	cmn	sp,#0			@ [+3], clear carry to denote 20_39
++.L_20_39_or_60_79:
++___
++for($i=0;$i<5;$i++) {
++	&BODY_20_39(@V);	unshift(@V,pop(@V));
++}
++$code.=<<___;
++	teq	$Xi,sp			@ preserve carry
++	bne	.L_20_39_or_60_79	@ [+((12+3)*5+2)*4]
++	bcs	.L_done			@ [+((12+3)*5+2)*4], spare 300 bytes
++
++	ldr	$K,.LK_40_59
++	sub	sp,sp,#20*4		@ [+2]
++.L_40_59:
++___
++for($i=0;$i<5;$i++) {
++	&BODY_40_59(@V);	unshift(@V,pop(@V));
++}
++$code.=<<___;
++	teq	$Xi,sp
++	bne	.L_40_59		@ [+((12+5)*5+2)*4]
++
++	ldr	$K,.LK_60_79
++	sub	sp,sp,#20*4
++	cmp	sp,#0			@ set carry to denote 60_79
++	b	.L_20_39_or_60_79	@ [+4], spare 300 bytes
++.L_done:
++	add	sp,sp,#80*4		@ "deallocate" stack frame
++	ldmia	$ctx,{$K,$t0,$t1,$t2,$Xi}
++	add	$a,$K,$a
++	add	$b,$t0,$b
++	add	$c,$t1,$c,ror#2
++	add	$d,$t2,$d,ror#2
++	add	$e,$Xi,$e,ror#2
++	stmia	$ctx,{$a,$b,$c,$d,$e}
++	teq	$inp,$len
++	bne	.Lloop			@ [+18], total 1307
++
++	ldmia	sp!,{r4-r12,lr}
++	tst	lr,#1
++	moveq	pc,lr			@ be binary compatible with V4, yet
++	bx	lr			@ interoperable with Thumb ISA:-)
++.align	2
++.LK_00_19:	.word	0x5a827999
++.LK_20_39:	.word	0x6ed9eba1
++.LK_40_59:	.word	0x8f1bbcdc
++.LK_60_79:	.word	0xca62c1d6
++.size	sha1_block_data_order,.-sha1_block_data_order
++.asciz	"SHA1 block transform 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; # enforce flush
+--- /dev/null	2009-04-24 06:09:48.000000000 -0700
++++ openssl-0.9.8h/crypto/0.9.9-dev/sha/sha1-armv4-large.s	2009-09-03 15:42:39.000000000 -0700
+@@ -0,0 +1,376 @@
++.text
++
++.global	sha1_block_data_order
++.type	sha1_block_data_order,%function
++
++.align	2
++sha1_block_data_order:
++	stmdb	sp!,{r4-r12,lr}
++	add	r2,r1,r2,lsl#6	@ r2 to point at the end of r1
++	ldmia	r0,{r3,r4,r5,r6,r7}
++.Lloop:
++	ldr	r8,.LK_00_19
++	mov	r14,sp
++	sub	sp,sp,#15*4
++	mov	r5,r5,ror#30
++	mov	r6,r6,ror#30
++	mov	r7,r7,ror#30		@ [6]
++.L_00_15:
++	ldrb	r10,[r1],#4
++	ldrb	r11,[r1,#-3]
++	ldrb	r12,[r1,#-2]
++	add	r7,r8,r7,ror#2			@ E+=K_00_19
++	orr	r10,r11,r10,lsl#8
++	ldrb	r11,[r1,#-1]
++	orr	r10,r12,r10,lsl#8
++	add	r7,r7,r3,ror#27			@ E+=ROR(A,27)
++	orr	r10,r11,r10,lsl#8
++	add	r7,r7,r10			@ E+=X[i]
++	eor	r11,r5,r6			@ F_xx_xx
++	str	r10,[r14,#-4]!
++	and	r11,r4,r11,ror#2
++	eor	r11,r11,r6,ror#2		@ F_00_19(B,C,D)
++	add	r7,r7,r11			@ E+=F_00_19(B,C,D)
++	ldrb	r10,[r1],#4
++	ldrb	r11,[r1,#-3]
++	ldrb	r12,[r1,#-2]
++	add	r6,r8,r6,ror#2			@ E+=K_00_19
++	orr	r10,r11,r10,lsl#8
++	ldrb	r11,[r1,#-1]
++	orr	r10,r12,r10,lsl#8
++	add	r6,r6,r7,ror#27			@ E+=ROR(A,27)
++	orr	r10,r11,r10,lsl#8
++	add	r6,r6,r10			@ E+=X[i]
++	eor	r11,r4,r5			@ F_xx_xx
++	str	r10,[r14,#-4]!
++	and	r11,r3,r11,ror#2
++	eor	r11,r11,r5,ror#2		@ F_00_19(B,C,D)
++	add	r6,r6,r11			@ E+=F_00_19(B,C,D)
++	ldrb	r10,[r1],#4
++	ldrb	r11,[r1,#-3]
++	ldrb	r12,[r1,#-2]
++	add	r5,r8,r5,ror#2			@ E+=K_00_19
++	orr	r10,r11,r10,lsl#8
++	ldrb	r11,[r1,#-1]
++	orr	r10,r12,r10,lsl#8
++	add	r5,r5,r6,ror#27			@ E+=ROR(A,27)
++	orr	r10,r11,r10,lsl#8
++	add	r5,r5,r10			@ E+=X[i]
++	eor	r11,r3,r4			@ F_xx_xx
++	str	r10,[r14,#-4]!
++	and	r11,r7,r11,ror#2
++	eor	r11,r11,r4,ror#2		@ F_00_19(B,C,D)
++	add	r5,r5,r11			@ E+=F_00_19(B,C,D)
++	ldrb	r10,[r1],#4
++	ldrb	r11,[r1,#-3]
++	ldrb	r12,[r1,#-2]
++	add	r4,r8,r4,ror#2			@ E+=K_00_19
++	orr	r10,r11,r10,lsl#8
++	ldrb	r11,[r1,#-1]
++	orr	r10,r12,r10,lsl#8
++	add	r4,r4,r5,ror#27			@ E+=ROR(A,27)
++	orr	r10,r11,r10,lsl#8
++	add	r4,r4,r10			@ E+=X[i]
++	eor	r11,r7,r3			@ F_xx_xx
++	str	r10,[r14,#-4]!
++	and	r11,r6,r11,ror#2
++	eor	r11,r11,r3,ror#2		@ F_00_19(B,C,D)
++	add	r4,r4,r11			@ E+=F_00_19(B,C,D)
++	ldrb	r10,[r1],#4
++	ldrb	r11,[r1,#-3]
++	ldrb	r12,[r1,#-2]
++	add	r3,r8,r3,ror#2			@ E+=K_00_19
++	orr	r10,r11,r10,lsl#8
++	ldrb	r11,[r1,#-1]
++	orr	r10,r12,r10,lsl#8
++	add	r3,r3,r4,ror#27			@ E+=ROR(A,27)
++	orr	r10,r11,r10,lsl#8
++	add	r3,r3,r10			@ E+=X[i]
++	eor	r11,r6,r7			@ F_xx_xx
++	str	r10,[r14,#-4]!
++	and	r11,r5,r11,ror#2
++	eor	r11,r11,r7,ror#2		@ F_00_19(B,C,D)
++	add	r3,r3,r11			@ E+=F_00_19(B,C,D)
++	teq	r14,sp
++	bne	.L_00_15		@ [((11+4)*5+2)*3]
++	ldrb	r10,[r1],#4
++	ldrb	r11,[r1,#-3]
++	ldrb	r12,[r1,#-2]
++	add	r7,r8,r7,ror#2			@ E+=K_00_19
++	orr	r10,r11,r10,lsl#8
++	ldrb	r11,[r1,#-1]
++	orr	r10,r12,r10,lsl#8
++	add	r7,r7,r3,ror#27			@ E+=ROR(A,27)
++	orr	r10,r11,r10,lsl#8
++	add	r7,r7,r10			@ E+=X[i]
++	eor	r11,r5,r6			@ F_xx_xx
++	str	r10,[r14,#-4]!
++	and	r11,r4,r11,ror#2
++	eor	r11,r11,r6,ror#2		@ F_00_19(B,C,D)
++	add	r7,r7,r11			@ E+=F_00_19(B,C,D)
++	ldr	r10,[r14,#15*4]
++	ldr	r11,[r14,#13*4]
++	ldr	r12,[r14,#7*4]
++	add	r6,r8,r6,ror#2			@ E+=K_xx_xx
++	eor	r10,r10,r11
++	ldr	r11,[r14,#2*4]
++	add	r6,r6,r7,ror#27			@ E+=ROR(A,27)
++	eor	r10,r10,r12
++	eor	r10,r10,r11
++	eor	r11,r4,r5			@ F_xx_xx, but not in 40_59
++	mov	r10,r10,ror#31
++	add	r6,r6,r10			@ E+=X[i]
++	str	r10,[r14,#-4]!
++	and	r11,r3,r11,ror#2
++	eor	r11,r11,r5,ror#2		@ F_00_19(B,C,D)
++	add	r6,r6,r11			@ E+=F_00_19(B,C,D)
++	ldr	r10,[r14,#15*4]
++	ldr	r11,[r14,#13*4]
++	ldr	r12,[r14,#7*4]
++	add	r5,r8,r5,ror#2			@ E+=K_xx_xx
++	eor	r10,r10,r11
++	ldr	r11,[r14,#2*4]
++	add	r5,r5,r6,ror#27			@ E+=ROR(A,27)
++	eor	r10,r10,r12
++	eor	r10,r10,r11
++	eor	r11,r3,r4			@ F_xx_xx, but not in 40_59
++	mov	r10,r10,ror#31
++	add	r5,r5,r10			@ E+=X[i]
++	str	r10,[r14,#-4]!
++	and	r11,r7,r11,ror#2
++	eor	r11,r11,r4,ror#2		@ F_00_19(B,C,D)
++	add	r5,r5,r11			@ E+=F_00_19(B,C,D)
++	ldr	r10,[r14,#15*4]
++	ldr	r11,[r14,#13*4]
++	ldr	r12,[r14,#7*4]
++	add	r4,r8,r4,ror#2			@ E+=K_xx_xx
++	eor	r10,r10,r11
++	ldr	r11,[r14,#2*4]
++	add	r4,r4,r5,ror#27			@ E+=ROR(A,27)
++	eor	r10,r10,r12
++	eor	r10,r10,r11
++	eor	r11,r7,r3			@ F_xx_xx, but not in 40_59
++	mov	r10,r10,ror#31
++	add	r4,r4,r10			@ E+=X[i]
++	str	r10,[r14,#-4]!
++	and	r11,r6,r11,ror#2
++	eor	r11,r11,r3,ror#2		@ F_00_19(B,C,D)
++	add	r4,r4,r11			@ E+=F_00_19(B,C,D)
++	ldr	r10,[r14,#15*4]
++	ldr	r11,[r14,#13*4]
++	ldr	r12,[r14,#7*4]
++	add	r3,r8,r3,ror#2			@ E+=K_xx_xx
++	eor	r10,r10,r11
++	ldr	r11,[r14,#2*4]
++	add	r3,r3,r4,ror#27			@ E+=ROR(A,27)
++	eor	r10,r10,r12
++	eor	r10,r10,r11
++	eor	r11,r6,r7			@ F_xx_xx, but not in 40_59
++	mov	r10,r10,ror#31
++	add	r3,r3,r10			@ E+=X[i]
++	str	r10,[r14,#-4]!
++	and	r11,r5,r11,ror#2
++	eor	r11,r11,r7,ror#2		@ F_00_19(B,C,D)
++	add	r3,r3,r11			@ E+=F_00_19(B,C,D)
++
++	ldr	r8,.LK_20_39		@ [+15+16*4]
++	sub	sp,sp,#25*4
++	cmn	sp,#0			@ [+3], clear carry to denote 20_39
++.L_20_39_or_60_79:
++	ldr	r10,[r14,#15*4]
++	ldr	r11,[r14,#13*4]
++	ldr	r12,[r14,#7*4]
++	add	r7,r8,r7,ror#2			@ E+=K_xx_xx
++	eor	r10,r10,r11
++	ldr	r11,[r14,#2*4]
++	add	r7,r7,r3,ror#27			@ E+=ROR(A,27)
++	eor	r10,r10,r12
++	eor	r10,r10,r11
++	eor	r11,r5,r6			@ F_xx_xx, but not in 40_59
++	mov	r10,r10,ror#31
++	add	r7,r7,r10			@ E+=X[i]
++	str	r10,[r14,#-4]!
++	eor	r11,r4,r11,ror#2		@ F_20_39(B,C,D)
++	add	r7,r7,r11			@ E+=F_20_39(B,C,D)
++	ldr	r10,[r14,#15*4]
++	ldr	r11,[r14,#13*4]
++	ldr	r12,[r14,#7*4]
++	add	r6,r8,r6,ror#2			@ E+=K_xx_xx
++	eor	r10,r10,r11
++	ldr	r11,[r14,#2*4]
++	add	r6,r6,r7,ror#27			@ E+=ROR(A,27)
++	eor	r10,r10,r12
++	eor	r10,r10,r11
++	eor	r11,r4,r5			@ F_xx_xx, but not in 40_59
++	mov	r10,r10,ror#31
++	add	r6,r6,r10			@ E+=X[i]
++	str	r10,[r14,#-4]!
++	eor	r11,r3,r11,ror#2		@ F_20_39(B,C,D)
++	add	r6,r6,r11			@ E+=F_20_39(B,C,D)
++	ldr	r10,[r14,#15*4]
++	ldr	r11,[r14,#13*4]
++	ldr	r12,[r14,#7*4]
++	add	r5,r8,r5,ror#2			@ E+=K_xx_xx
++	eor	r10,r10,r11
++	ldr	r11,[r14,#2*4]
++	add	r5,r5,r6,ror#27			@ E+=ROR(A,27)
++	eor	r10,r10,r12
++	eor	r10,r10,r11
++	eor	r11,r3,r4			@ F_xx_xx, but not in 40_59
++	mov	r10,r10,ror#31
++	add	r5,r5,r10			@ E+=X[i]
++	str	r10,[r14,#-4]!
++	eor	r11,r7,r11,ror#2		@ F_20_39(B,C,D)
++	add	r5,r5,r11			@ E+=F_20_39(B,C,D)
++	ldr	r10,[r14,#15*4]
++	ldr	r11,[r14,#13*4]
++	ldr	r12,[r14,#7*4]
++	add	r4,r8,r4,ror#2			@ E+=K_xx_xx
++	eor	r10,r10,r11
++	ldr	r11,[r14,#2*4]
++	add	r4,r4,r5,ror#27			@ E+=ROR(A,27)
++	eor	r10,r10,r12
++	eor	r10,r10,r11
++	eor	r11,r7,r3			@ F_xx_xx, but not in 40_59
++	mov	r10,r10,ror#31
++	add	r4,r4,r10			@ E+=X[i]
++	str	r10,[r14,#-4]!
++	eor	r11,r6,r11,ror#2		@ F_20_39(B,C,D)
++	add	r4,r4,r11			@ E+=F_20_39(B,C,D)
++	ldr	r10,[r14,#15*4]
++	ldr	r11,[r14,#13*4]
++	ldr	r12,[r14,#7*4]
++	add	r3,r8,r3,ror#2			@ E+=K_xx_xx
++	eor	r10,r10,r11
++	ldr	r11,[r14,#2*4]
++	add	r3,r3,r4,ror#27			@ E+=ROR(A,27)
++	eor	r10,r10,r12
++	eor	r10,r10,r11
++	eor	r11,r6,r7			@ F_xx_xx, but not in 40_59
++	mov	r10,r10,ror#31
++	add	r3,r3,r10			@ E+=X[i]
++	str	r10,[r14,#-4]!
++	eor	r11,r5,r11,ror#2		@ F_20_39(B,C,D)
++	add	r3,r3,r11			@ E+=F_20_39(B,C,D)
++	teq	r14,sp			@ preserve carry
++	bne	.L_20_39_or_60_79	@ [+((12+3)*5+2)*4]
++	bcs	.L_done			@ [+((12+3)*5+2)*4], spare 300 bytes
++
++	ldr	r8,.LK_40_59
++	sub	sp,sp,#20*4		@ [+2]
++.L_40_59:
++	ldr	r10,[r14,#15*4]
++	ldr	r11,[r14,#13*4]
++	ldr	r12,[r14,#7*4]
++	add	r7,r8,r7,ror#2			@ E+=K_xx_xx
++	eor	r10,r10,r11
++	ldr	r11,[r14,#2*4]
++	add	r7,r7,r3,ror#27			@ E+=ROR(A,27)
++	eor	r10,r10,r12
++	eor	r10,r10,r11
++	mov	r10,r10,ror#31
++	add	r7,r7,r10			@ E+=X[i]
++	str	r10,[r14,#-4]!
++	and	r11,r4,r5,ror#2
++	orr	r12,r4,r5,ror#2
++	and	r12,r12,r6,ror#2
++	orr	r11,r11,r12			@ F_40_59(B,C,D)
++	add	r7,r7,r11			@ E+=F_40_59(B,C,D)
++	ldr	r10,[r14,#15*4]
++	ldr	r11,[r14,#13*4]
++	ldr	r12,[r14,#7*4]
++	add	r6,r8,r6,ror#2			@ E+=K_xx_xx
++	eor	r10,r10,r11
++	ldr	r11,[r14,#2*4]
++	add	r6,r6,r7,ror#27			@ E+=ROR(A,27)
++	eor	r10,r10,r12
++	eor	r10,r10,r11
++	mov	r10,r10,ror#31
++	add	r6,r6,r10			@ E+=X[i]
++	str	r10,[r14,#-4]!
++	and	r11,r3,r4,ror#2
++	orr	r12,r3,r4,ror#2
++	and	r12,r12,r5,ror#2
++	orr	r11,r11,r12			@ F_40_59(B,C,D)
++	add	r6,r6,r11			@ E+=F_40_59(B,C,D)
++	ldr	r10,[r14,#15*4]
++	ldr	r11,[r14,#13*4]
++	ldr	r12,[r14,#7*4]
++	add	r5,r8,r5,ror#2			@ E+=K_xx_xx
++	eor	r10,r10,r11
++	ldr	r11,[r14,#2*4]
++	add	r5,r5,r6,ror#27			@ E+=ROR(A,27)
++	eor	r10,r10,r12
++	eor	r10,r10,r11
++	mov	r10,r10,ror#31
++	add	r5,r5,r10			@ E+=X[i]
++	str	r10,[r14,#-4]!
++	and	r11,r7,r3,ror#2
++	orr	r12,r7,r3,ror#2
++	and	r12,r12,r4,ror#2
++	orr	r11,r11,r12			@ F_40_59(B,C,D)
++	add	r5,r5,r11			@ E+=F_40_59(B,C,D)
++	ldr	r10,[r14,#15*4]
++	ldr	r11,[r14,#13*4]
++	ldr	r12,[r14,#7*4]
++	add	r4,r8,r4,ror#2			@ E+=K_xx_xx
++	eor	r10,r10,r11
++	ldr	r11,[r14,#2*4]
++	add	r4,r4,r5,ror#27			@ E+=ROR(A,27)
++	eor	r10,r10,r12
++	eor	r10,r10,r11
++	mov	r10,r10,ror#31
++	add	r4,r4,r10			@ E+=X[i]
++	str	r10,[r14,#-4]!
++	and	r11,r6,r7,ror#2
++	orr	r12,r6,r7,ror#2
++	and	r12,r12,r3,ror#2
++	orr	r11,r11,r12			@ F_40_59(B,C,D)
++	add	r4,r4,r11			@ E+=F_40_59(B,C,D)
++	ldr	r10,[r14,#15*4]
++	ldr	r11,[r14,#13*4]
++	ldr	r12,[r14,#7*4]
++	add	r3,r8,r3,ror#2			@ E+=K_xx_xx
++	eor	r10,r10,r11
++	ldr	r11,[r14,#2*4]
++	add	r3,r3,r4,ror#27			@ E+=ROR(A,27)
++	eor	r10,r10,r12
++	eor	r10,r10,r11
++	mov	r10,r10,ror#31
++	add	r3,r3,r10			@ E+=X[i]
++	str	r10,[r14,#-4]!
++	and	r11,r5,r6,ror#2
++	orr	r12,r5,r6,ror#2
++	and	r12,r12,r7,ror#2
++	orr	r11,r11,r12			@ F_40_59(B,C,D)
++	add	r3,r3,r11			@ E+=F_40_59(B,C,D)
++	teq	r14,sp
++	bne	.L_40_59		@ [+((12+5)*5+2)*4]
++
++	ldr	r8,.LK_60_79
++	sub	sp,sp,#20*4
++	cmp	sp,#0			@ set carry to denote 60_79
++	b	.L_20_39_or_60_79	@ [+4], spare 300 bytes
++.L_done:
++	add	sp,sp,#80*4		@ "deallocate" stack frame
++	ldmia	r0,{r8,r10,r11,r12,r14}
++	add	r3,r8,r3
++	add	r4,r10,r4
++	add	r5,r11,r5,ror#2
++	add	r6,r12,r6,ror#2
++	add	r7,r14,r7,ror#2
++	stmia	r0,{r3,r4,r5,r6,r7}
++	teq	r1,r2
++	bne	.Lloop			@ [+18], total 1307
++
++	ldmia	sp!,{r4-r12,lr}
++	tst	lr,#1
++	moveq	pc,lr			@ be binary compatible with V4, yet
++	.word	0xe12fff1e			@ interoperable with Thumb ISA:-)
++.align	2
++.LK_00_19:	.word	0x5a827999
++.LK_20_39:	.word	0x6ed9eba1
++.LK_40_59:	.word	0x8f1bbcdc
++.LK_60_79:	.word	0xca62c1d6
++.size	sha1_block_data_order,.-sha1_block_data_order
++.asciz	"SHA1 block transform for ARMv4, CRYPTOGAMS by <[email protected]>"
+--- /dev/null	2009-04-24 06:09:48.000000000 -0700
++++ openssl-0.9.8h/crypto/0.9.9-dev/sha/sha256-armv4.pl	2009-09-03 15:42:39.000000000 -0700
+@@ -0,0 +1,180 @@
++#!/usr/bin/env perl
++
++# ====================================================================
++# Written by Andy Polyakov <[email protected]> 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/.
++# ====================================================================
++
++# SHA256 block procedure for ARMv4. May 2007.
++
++# Performance is ~2x better than gcc 3.4 generated code and in "abso-
++# lute" terms is ~2250 cycles per 64-byte block or ~35 cycles per
++# byte.
++
++$output=shift;
++open STDOUT,">$output";
++
++$ctx="r0";	$t0="r0";
++$inp="r1";
++$len="r2";	$t1="r2";
++$T1="r3";
++$A="r4";
++$B="r5";
++$C="r6";
++$D="r7";
++$E="r8";
++$F="r9";
++$G="r10";
++$H="r11";
++@V=($A,$B,$C,$D,$E,$F,$G,$H);
++$t2="r12";
++$Ktbl="r14";
++
++@Sigma0=( 2,13,22);
++@Sigma1=( 6,11,25);
++@sigma0=( 7,18, 3);
++@sigma1=(17,19,10);
++
++sub BODY_00_15 {
++my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
++
++$code.=<<___ if ($i<16);
++	ldrb	$T1,[$inp,#3]			@ $i
++	ldrb	$t2,[$inp,#2]
++	ldrb	$t1,[$inp,#1]
++	ldrb	$t0,[$inp],#4
++	orr	$T1,$T1,$t2,lsl#8
++	orr	$T1,$T1,$t1,lsl#16
++	orr	$T1,$T1,$t0,lsl#24
++	`"str	$inp,[sp,#17*4]"	if ($i==15)`
++___
++$code.=<<___;
++	ldr	$t2,[$Ktbl],#4			@ *K256++
++	str	$T1,[sp,#`$i%16`*4]
++	mov	$t0,$e,ror#$Sigma1[0]
++	eor	$t0,$t0,$e,ror#$Sigma1[1]
++	eor	$t0,$t0,$e,ror#$Sigma1[2]	@ Sigma1(e)
++	add	$T1,$T1,$t0
++	eor	$t1,$f,$g
++	and	$t1,$t1,$e
++	eor	$t1,$t1,$g			@ Ch(e,f,g)
++	add	$T1,$T1,$t1
++	add	$T1,$T1,$h
++	add	$T1,$T1,$t2
++	mov	$h,$a,ror#$Sigma0[0]
++	eor	$h,$h,$a,ror#$Sigma0[1]
++	eor	$h,$h,$a,ror#$Sigma0[2]		@ Sigma0(a)
++	orr	$t0,$a,$b
++	and	$t0,$t0,$c
++	and	$t1,$a,$b
++	orr	$t0,$t0,$t1			@ Maj(a,b,c)
++	add	$h,$h,$t0
++	add	$d,$d,$T1
++	add	$h,$h,$T1
++___
++}
++
++sub BODY_16_XX {
++my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_;
++
++$code.=<<___;
++	ldr	$t1,[sp,#`($i+1)%16`*4]	@ $i
++	ldr	$t2,[sp,#`($i+14)%16`*4]
++	ldr	$T1,[sp,#`($i+0)%16`*4]
++	ldr	$inp,[sp,#`($i+9)%16`*4]
++	mov	$t0,$t1,ror#$sigma0[0]
++	eor	$t0,$t0,$t1,ror#$sigma0[1]
++	eor	$t0,$t0,$t1,lsr#$sigma0[2]	@ sigma0(X[i+1])
++	mov	$t1,$t2,ror#$sigma1[0]
++	eor	$t1,$t1,$t2,ror#$sigma1[1]
++	eor	$t1,$t1,$t2,lsr#$sigma1[2]	@ sigma1(X[i+14])
++	add	$T1,$T1,$t0
++	add	$T1,$T1,$t1
++	add	$T1,$T1,$inp
++___
++	&BODY_00_15(@_);
++}
++
++$code=<<___;
++.text
++.code	32
++
++.type	K256,%object
++.align	5
++K256:
++.word	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
++.word	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
++.word	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
++.word	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
++.word	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
++.word	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
++.word	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
++.word	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
++.word	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
++.word	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
++.word	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
++.word	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
++.word	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
++.word	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
++.word	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
++.word	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
++.size	K256,.-K256
++
++.global	sha256_block_data_order
++.type	sha256_block_data_order,%function
++sha256_block_data_order:
++	sub	r3,pc,#8		@ sha256_block_data_order
++	add	$len,$inp,$len,lsl#6	@ len to point at the end of inp
++	stmdb	sp!,{$ctx,$inp,$len,r4-r12,lr}
++	ldmia	$ctx,{$A,$B,$C,$D,$E,$F,$G,$H}
++	sub	$Ktbl,r3,#256		@ K256
++	sub	sp,sp,#16*4		@ alloca(X[16])
++.Loop:
++___
++for($i=0;$i<16;$i++)	{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); }
++$code.=".Lrounds_16_xx:\n";
++for (;$i<32;$i++)	{ &BODY_16_XX($i,@V); unshift(@V,pop(@V)); }
++$code.=<<___;
++	and	$t2,$t2,#0xff
++	cmp	$t2,#0xf2
++	bne	.Lrounds_16_xx
++
++	ldr	$T1,[sp,#16*4]		@ pull ctx
++	ldr	$t0,[$T1,#0]
++	ldr	$t1,[$T1,#4]
++	ldr	$t2,[$T1,#8]
++	add	$A,$A,$t0
++	ldr	$t0,[$T1,#12]
++	add	$B,$B,$t1
++	ldr	$t1,[$T1,#16]
++	add	$C,$C,$t2
++	ldr	$t2,[$T1,#20]
++	add	$D,$D,$t0
++	ldr	$t0,[$T1,#24]
++	add	$E,$E,$t1
++	ldr	$t1,[$T1,#28]
++	add	$F,$F,$t2
++	ldr	$inp,[sp,#17*4]		@ pull inp
++	ldr	$t2,[sp,#18*4]		@ pull inp+len
++	add	$G,$G,$t0
++	add	$H,$H,$t1
++	stmia	$T1,{$A,$B,$C,$D,$E,$F,$G,$H}
++	cmp	$inp,$t2
++	sub	$Ktbl,$Ktbl,#256	@ rewind Ktbl
++	bne	.Loop
++
++	add	sp,sp,#`16+3`*4	@ destroy frame
++	ldmia	sp!,{r4-r12,lr}
++	tst	lr,#1
++	moveq	pc,lr			@ be binary compatible with V4, yet
++	bx	lr			@ interoperable with Thumb ISA:-)
++.size   sha256_block_data_order,.-sha256_block_data_order
++.asciz  "SHA256 block transform for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
++___
++
++$code =~ s/\`([^\`]*)\`/eval $1/gem;
++$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
++print $code;
++close STDOUT; # enforce flush
+--- /dev/null	2009-04-24 06:09:48.000000000 -0700
++++ openssl-0.9.8h/crypto/0.9.9-dev/sha/sha256-armv4.s	2009-09-03 15:42:39.000000000 -0700
+@@ -0,0 +1,1110 @@
++.text
++.code	32
++
++.type	K256,%object
++.align	5
++K256:
++.word	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
++.word	0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
++.word	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
++.word	0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
++.word	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
++.word	0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
++.word	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
++.word	0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
++.word	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
++.word	0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
++.word	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
++.word	0xd192e819,0xd6990624,0xf40e3585,0x106aa070
++.word	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
++.word	0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
++.word	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
++.word	0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
++.size	K256,.-K256
++
++.global	sha256_block_data_order
++.type	sha256_block_data_order,%function
++sha256_block_data_order:
++	sub	r3,pc,#8		@ sha256_block_data_order
++	add	r2,r1,r2,lsl#6	@ len to point at the end of inp
++	stmdb	sp!,{r0,r1,r2,r4-r12,lr}
++	ldmia	r0,{r4,r5,r6,r7,r8,r9,r10,r11}
++	sub	r14,r3,#256		@ K256
++	sub	sp,sp,#16*4		@ alloca(X[16])
++.Loop:
++	ldrb	r3,[r1,#3]			@ 0
++	ldrb	r12,[r1,#2]
++	ldrb	r2,[r1,#1]
++	ldrb	r0,[r1],#4
++	orr	r3,r3,r12,lsl#8
++	orr	r3,r3,r2,lsl#16
++	orr	r3,r3,r0,lsl#24
++	
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#0*4]
++	mov	r0,r8,ror#6
++	eor	r0,r0,r8,ror#11
++	eor	r0,r0,r8,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r9,r10
++	and	r2,r2,r8
++	eor	r2,r2,r10			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r11
++	add	r3,r3,r12
++	mov	r11,r4,ror#2
++	eor	r11,r11,r4,ror#13
++	eor	r11,r11,r4,ror#22		@ Sigma0(a)
++	orr	r0,r4,r5
++	and	r0,r0,r6
++	and	r2,r4,r5
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r11,r11,r0
++	add	r7,r7,r3
++	add	r11,r11,r3
++	ldrb	r3,[r1,#3]			@ 1
++	ldrb	r12,[r1,#2]
++	ldrb	r2,[r1,#1]
++	ldrb	r0,[r1],#4
++	orr	r3,r3,r12,lsl#8
++	orr	r3,r3,r2,lsl#16
++	orr	r3,r3,r0,lsl#24
++	
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#1*4]
++	mov	r0,r7,ror#6
++	eor	r0,r0,r7,ror#11
++	eor	r0,r0,r7,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r8,r9
++	and	r2,r2,r7
++	eor	r2,r2,r9			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r10
++	add	r3,r3,r12
++	mov	r10,r11,ror#2
++	eor	r10,r10,r11,ror#13
++	eor	r10,r10,r11,ror#22		@ Sigma0(a)
++	orr	r0,r11,r4
++	and	r0,r0,r5
++	and	r2,r11,r4
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r10,r10,r0
++	add	r6,r6,r3
++	add	r10,r10,r3
++	ldrb	r3,[r1,#3]			@ 2
++	ldrb	r12,[r1,#2]
++	ldrb	r2,[r1,#1]
++	ldrb	r0,[r1],#4
++	orr	r3,r3,r12,lsl#8
++	orr	r3,r3,r2,lsl#16
++	orr	r3,r3,r0,lsl#24
++	
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#2*4]
++	mov	r0,r6,ror#6
++	eor	r0,r0,r6,ror#11
++	eor	r0,r0,r6,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r7,r8
++	and	r2,r2,r6
++	eor	r2,r2,r8			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r9
++	add	r3,r3,r12
++	mov	r9,r10,ror#2
++	eor	r9,r9,r10,ror#13
++	eor	r9,r9,r10,ror#22		@ Sigma0(a)
++	orr	r0,r10,r11
++	and	r0,r0,r4
++	and	r2,r10,r11
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r9,r9,r0
++	add	r5,r5,r3
++	add	r9,r9,r3
++	ldrb	r3,[r1,#3]			@ 3
++	ldrb	r12,[r1,#2]
++	ldrb	r2,[r1,#1]
++	ldrb	r0,[r1],#4
++	orr	r3,r3,r12,lsl#8
++	orr	r3,r3,r2,lsl#16
++	orr	r3,r3,r0,lsl#24
++	
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#3*4]
++	mov	r0,r5,ror#6
++	eor	r0,r0,r5,ror#11
++	eor	r0,r0,r5,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r6,r7
++	and	r2,r2,r5
++	eor	r2,r2,r7			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r8
++	add	r3,r3,r12
++	mov	r8,r9,ror#2
++	eor	r8,r8,r9,ror#13
++	eor	r8,r8,r9,ror#22		@ Sigma0(a)
++	orr	r0,r9,r10
++	and	r0,r0,r11
++	and	r2,r9,r10
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r8,r8,r0
++	add	r4,r4,r3
++	add	r8,r8,r3
++	ldrb	r3,[r1,#3]			@ 4
++	ldrb	r12,[r1,#2]
++	ldrb	r2,[r1,#1]
++	ldrb	r0,[r1],#4
++	orr	r3,r3,r12,lsl#8
++	orr	r3,r3,r2,lsl#16
++	orr	r3,r3,r0,lsl#24
++	
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#4*4]
++	mov	r0,r4,ror#6
++	eor	r0,r0,r4,ror#11
++	eor	r0,r0,r4,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r5,r6
++	and	r2,r2,r4
++	eor	r2,r2,r6			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r7
++	add	r3,r3,r12
++	mov	r7,r8,ror#2
++	eor	r7,r7,r8,ror#13
++	eor	r7,r7,r8,ror#22		@ Sigma0(a)
++	orr	r0,r8,r9
++	and	r0,r0,r10
++	and	r2,r8,r9
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r7,r7,r0
++	add	r11,r11,r3
++	add	r7,r7,r3
++	ldrb	r3,[r1,#3]			@ 5
++	ldrb	r12,[r1,#2]
++	ldrb	r2,[r1,#1]
++	ldrb	r0,[r1],#4
++	orr	r3,r3,r12,lsl#8
++	orr	r3,r3,r2,lsl#16
++	orr	r3,r3,r0,lsl#24
++	
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#5*4]
++	mov	r0,r11,ror#6
++	eor	r0,r0,r11,ror#11
++	eor	r0,r0,r11,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r4,r5
++	and	r2,r2,r11
++	eor	r2,r2,r5			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r6
++	add	r3,r3,r12
++	mov	r6,r7,ror#2
++	eor	r6,r6,r7,ror#13
++	eor	r6,r6,r7,ror#22		@ Sigma0(a)
++	orr	r0,r7,r8
++	and	r0,r0,r9
++	and	r2,r7,r8
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r6,r6,r0
++	add	r10,r10,r3
++	add	r6,r6,r3
++	ldrb	r3,[r1,#3]			@ 6
++	ldrb	r12,[r1,#2]
++	ldrb	r2,[r1,#1]
++	ldrb	r0,[r1],#4
++	orr	r3,r3,r12,lsl#8
++	orr	r3,r3,r2,lsl#16
++	orr	r3,r3,r0,lsl#24
++	
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#6*4]
++	mov	r0,r10,ror#6
++	eor	r0,r0,r10,ror#11
++	eor	r0,r0,r10,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r11,r4
++	and	r2,r2,r10
++	eor	r2,r2,r4			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r5
++	add	r3,r3,r12
++	mov	r5,r6,ror#2
++	eor	r5,r5,r6,ror#13
++	eor	r5,r5,r6,ror#22		@ Sigma0(a)
++	orr	r0,r6,r7
++	and	r0,r0,r8
++	and	r2,r6,r7
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r5,r5,r0
++	add	r9,r9,r3
++	add	r5,r5,r3
++	ldrb	r3,[r1,#3]			@ 7
++	ldrb	r12,[r1,#2]
++	ldrb	r2,[r1,#1]
++	ldrb	r0,[r1],#4
++	orr	r3,r3,r12,lsl#8
++	orr	r3,r3,r2,lsl#16
++	orr	r3,r3,r0,lsl#24
++	
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#7*4]
++	mov	r0,r9,ror#6
++	eor	r0,r0,r9,ror#11
++	eor	r0,r0,r9,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r10,r11
++	and	r2,r2,r9
++	eor	r2,r2,r11			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r4
++	add	r3,r3,r12
++	mov	r4,r5,ror#2
++	eor	r4,r4,r5,ror#13
++	eor	r4,r4,r5,ror#22		@ Sigma0(a)
++	orr	r0,r5,r6
++	and	r0,r0,r7
++	and	r2,r5,r6
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r4,r4,r0
++	add	r8,r8,r3
++	add	r4,r4,r3
++	ldrb	r3,[r1,#3]			@ 8
++	ldrb	r12,[r1,#2]
++	ldrb	r2,[r1,#1]
++	ldrb	r0,[r1],#4
++	orr	r3,r3,r12,lsl#8
++	orr	r3,r3,r2,lsl#16
++	orr	r3,r3,r0,lsl#24
++	
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#8*4]
++	mov	r0,r8,ror#6
++	eor	r0,r0,r8,ror#11
++	eor	r0,r0,r8,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r9,r10
++	and	r2,r2,r8
++	eor	r2,r2,r10			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r11
++	add	r3,r3,r12
++	mov	r11,r4,ror#2
++	eor	r11,r11,r4,ror#13
++	eor	r11,r11,r4,ror#22		@ Sigma0(a)
++	orr	r0,r4,r5
++	and	r0,r0,r6
++	and	r2,r4,r5
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r11,r11,r0
++	add	r7,r7,r3
++	add	r11,r11,r3
++	ldrb	r3,[r1,#3]			@ 9
++	ldrb	r12,[r1,#2]
++	ldrb	r2,[r1,#1]
++	ldrb	r0,[r1],#4
++	orr	r3,r3,r12,lsl#8
++	orr	r3,r3,r2,lsl#16
++	orr	r3,r3,r0,lsl#24
++	
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#9*4]
++	mov	r0,r7,ror#6
++	eor	r0,r0,r7,ror#11
++	eor	r0,r0,r7,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r8,r9
++	and	r2,r2,r7
++	eor	r2,r2,r9			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r10
++	add	r3,r3,r12
++	mov	r10,r11,ror#2
++	eor	r10,r10,r11,ror#13
++	eor	r10,r10,r11,ror#22		@ Sigma0(a)
++	orr	r0,r11,r4
++	and	r0,r0,r5
++	and	r2,r11,r4
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r10,r10,r0
++	add	r6,r6,r3
++	add	r10,r10,r3
++	ldrb	r3,[r1,#3]			@ 10
++	ldrb	r12,[r1,#2]
++	ldrb	r2,[r1,#1]
++	ldrb	r0,[r1],#4
++	orr	r3,r3,r12,lsl#8
++	orr	r3,r3,r2,lsl#16
++	orr	r3,r3,r0,lsl#24
++	
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#10*4]
++	mov	r0,r6,ror#6
++	eor	r0,r0,r6,ror#11
++	eor	r0,r0,r6,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r7,r8
++	and	r2,r2,r6
++	eor	r2,r2,r8			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r9
++	add	r3,r3,r12
++	mov	r9,r10,ror#2
++	eor	r9,r9,r10,ror#13
++	eor	r9,r9,r10,ror#22		@ Sigma0(a)
++	orr	r0,r10,r11
++	and	r0,r0,r4
++	and	r2,r10,r11
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r9,r9,r0
++	add	r5,r5,r3
++	add	r9,r9,r3
++	ldrb	r3,[r1,#3]			@ 11
++	ldrb	r12,[r1,#2]
++	ldrb	r2,[r1,#1]
++	ldrb	r0,[r1],#4
++	orr	r3,r3,r12,lsl#8
++	orr	r3,r3,r2,lsl#16
++	orr	r3,r3,r0,lsl#24
++	
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#11*4]
++	mov	r0,r5,ror#6
++	eor	r0,r0,r5,ror#11
++	eor	r0,r0,r5,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r6,r7
++	and	r2,r2,r5
++	eor	r2,r2,r7			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r8
++	add	r3,r3,r12
++	mov	r8,r9,ror#2
++	eor	r8,r8,r9,ror#13
++	eor	r8,r8,r9,ror#22		@ Sigma0(a)
++	orr	r0,r9,r10
++	and	r0,r0,r11
++	and	r2,r9,r10
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r8,r8,r0
++	add	r4,r4,r3
++	add	r8,r8,r3
++	ldrb	r3,[r1,#3]			@ 12
++	ldrb	r12,[r1,#2]
++	ldrb	r2,[r1,#1]
++	ldrb	r0,[r1],#4
++	orr	r3,r3,r12,lsl#8
++	orr	r3,r3,r2,lsl#16
++	orr	r3,r3,r0,lsl#24
++	
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#12*4]
++	mov	r0,r4,ror#6
++	eor	r0,r0,r4,ror#11
++	eor	r0,r0,r4,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r5,r6
++	and	r2,r2,r4
++	eor	r2,r2,r6			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r7
++	add	r3,r3,r12
++	mov	r7,r8,ror#2
++	eor	r7,r7,r8,ror#13
++	eor	r7,r7,r8,ror#22		@ Sigma0(a)
++	orr	r0,r8,r9
++	and	r0,r0,r10
++	and	r2,r8,r9
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r7,r7,r0
++	add	r11,r11,r3
++	add	r7,r7,r3
++	ldrb	r3,[r1,#3]			@ 13
++	ldrb	r12,[r1,#2]
++	ldrb	r2,[r1,#1]
++	ldrb	r0,[r1],#4
++	orr	r3,r3,r12,lsl#8
++	orr	r3,r3,r2,lsl#16
++	orr	r3,r3,r0,lsl#24
++	
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#13*4]
++	mov	r0,r11,ror#6
++	eor	r0,r0,r11,ror#11
++	eor	r0,r0,r11,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r4,r5
++	and	r2,r2,r11
++	eor	r2,r2,r5			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r6
++	add	r3,r3,r12
++	mov	r6,r7,ror#2
++	eor	r6,r6,r7,ror#13
++	eor	r6,r6,r7,ror#22		@ Sigma0(a)
++	orr	r0,r7,r8
++	and	r0,r0,r9
++	and	r2,r7,r8
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r6,r6,r0
++	add	r10,r10,r3
++	add	r6,r6,r3
++	ldrb	r3,[r1,#3]			@ 14
++	ldrb	r12,[r1,#2]
++	ldrb	r2,[r1,#1]
++	ldrb	r0,[r1],#4
++	orr	r3,r3,r12,lsl#8
++	orr	r3,r3,r2,lsl#16
++	orr	r3,r3,r0,lsl#24
++	
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#14*4]
++	mov	r0,r10,ror#6
++	eor	r0,r0,r10,ror#11
++	eor	r0,r0,r10,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r11,r4
++	and	r2,r2,r10
++	eor	r2,r2,r4			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r5
++	add	r3,r3,r12
++	mov	r5,r6,ror#2
++	eor	r5,r5,r6,ror#13
++	eor	r5,r5,r6,ror#22		@ Sigma0(a)
++	orr	r0,r6,r7
++	and	r0,r0,r8
++	and	r2,r6,r7
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r5,r5,r0
++	add	r9,r9,r3
++	add	r5,r5,r3
++	ldrb	r3,[r1,#3]			@ 15
++	ldrb	r12,[r1,#2]
++	ldrb	r2,[r1,#1]
++	ldrb	r0,[r1],#4
++	orr	r3,r3,r12,lsl#8
++	orr	r3,r3,r2,lsl#16
++	orr	r3,r3,r0,lsl#24
++	str	r1,[sp,#17*4]
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#15*4]
++	mov	r0,r9,ror#6
++	eor	r0,r0,r9,ror#11
++	eor	r0,r0,r9,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r10,r11
++	and	r2,r2,r9
++	eor	r2,r2,r11			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r4
++	add	r3,r3,r12
++	mov	r4,r5,ror#2
++	eor	r4,r4,r5,ror#13
++	eor	r4,r4,r5,ror#22		@ Sigma0(a)
++	orr	r0,r5,r6
++	and	r0,r0,r7
++	and	r2,r5,r6
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r4,r4,r0
++	add	r8,r8,r3
++	add	r4,r4,r3
++.Lrounds_16_xx:
++	ldr	r2,[sp,#1*4]	@ 16
++	ldr	r12,[sp,#14*4]
++	ldr	r3,[sp,#0*4]
++	ldr	r1,[sp,#9*4]
++	mov	r0,r2,ror#7
++	eor	r0,r0,r2,ror#18
++	eor	r0,r0,r2,lsr#3	@ sigma0(X[i+1])
++	mov	r2,r12,ror#17
++	eor	r2,r2,r12,ror#19
++	eor	r2,r2,r12,lsr#10	@ sigma1(X[i+14])
++	add	r3,r3,r0
++	add	r3,r3,r2
++	add	r3,r3,r1
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#0*4]
++	mov	r0,r8,ror#6
++	eor	r0,r0,r8,ror#11
++	eor	r0,r0,r8,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r9,r10
++	and	r2,r2,r8
++	eor	r2,r2,r10			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r11
++	add	r3,r3,r12
++	mov	r11,r4,ror#2
++	eor	r11,r11,r4,ror#13
++	eor	r11,r11,r4,ror#22		@ Sigma0(a)
++	orr	r0,r4,r5
++	and	r0,r0,r6
++	and	r2,r4,r5
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r11,r11,r0
++	add	r7,r7,r3
++	add	r11,r11,r3
++	ldr	r2,[sp,#2*4]	@ 17
++	ldr	r12,[sp,#15*4]
++	ldr	r3,[sp,#1*4]
++	ldr	r1,[sp,#10*4]
++	mov	r0,r2,ror#7
++	eor	r0,r0,r2,ror#18
++	eor	r0,r0,r2,lsr#3	@ sigma0(X[i+1])
++	mov	r2,r12,ror#17
++	eor	r2,r2,r12,ror#19
++	eor	r2,r2,r12,lsr#10	@ sigma1(X[i+14])
++	add	r3,r3,r0
++	add	r3,r3,r2
++	add	r3,r3,r1
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#1*4]
++	mov	r0,r7,ror#6
++	eor	r0,r0,r7,ror#11
++	eor	r0,r0,r7,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r8,r9
++	and	r2,r2,r7
++	eor	r2,r2,r9			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r10
++	add	r3,r3,r12
++	mov	r10,r11,ror#2
++	eor	r10,r10,r11,ror#13
++	eor	r10,r10,r11,ror#22		@ Sigma0(a)
++	orr	r0,r11,r4
++	and	r0,r0,r5
++	and	r2,r11,r4
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r10,r10,r0
++	add	r6,r6,r3
++	add	r10,r10,r3
++	ldr	r2,[sp,#3*4]	@ 18
++	ldr	r12,[sp,#0*4]
++	ldr	r3,[sp,#2*4]
++	ldr	r1,[sp,#11*4]
++	mov	r0,r2,ror#7
++	eor	r0,r0,r2,ror#18
++	eor	r0,r0,r2,lsr#3	@ sigma0(X[i+1])
++	mov	r2,r12,ror#17
++	eor	r2,r2,r12,ror#19
++	eor	r2,r2,r12,lsr#10	@ sigma1(X[i+14])
++	add	r3,r3,r0
++	add	r3,r3,r2
++	add	r3,r3,r1
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#2*4]
++	mov	r0,r6,ror#6
++	eor	r0,r0,r6,ror#11
++	eor	r0,r0,r6,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r7,r8
++	and	r2,r2,r6
++	eor	r2,r2,r8			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r9
++	add	r3,r3,r12
++	mov	r9,r10,ror#2
++	eor	r9,r9,r10,ror#13
++	eor	r9,r9,r10,ror#22		@ Sigma0(a)
++	orr	r0,r10,r11
++	and	r0,r0,r4
++	and	r2,r10,r11
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r9,r9,r0
++	add	r5,r5,r3
++	add	r9,r9,r3
++	ldr	r2,[sp,#4*4]	@ 19
++	ldr	r12,[sp,#1*4]
++	ldr	r3,[sp,#3*4]
++	ldr	r1,[sp,#12*4]
++	mov	r0,r2,ror#7
++	eor	r0,r0,r2,ror#18
++	eor	r0,r0,r2,lsr#3	@ sigma0(X[i+1])
++	mov	r2,r12,ror#17
++	eor	r2,r2,r12,ror#19
++	eor	r2,r2,r12,lsr#10	@ sigma1(X[i+14])
++	add	r3,r3,r0
++	add	r3,r3,r2
++	add	r3,r3,r1
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#3*4]
++	mov	r0,r5,ror#6
++	eor	r0,r0,r5,ror#11
++	eor	r0,r0,r5,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r6,r7
++	and	r2,r2,r5
++	eor	r2,r2,r7			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r8
++	add	r3,r3,r12
++	mov	r8,r9,ror#2
++	eor	r8,r8,r9,ror#13
++	eor	r8,r8,r9,ror#22		@ Sigma0(a)
++	orr	r0,r9,r10
++	and	r0,r0,r11
++	and	r2,r9,r10
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r8,r8,r0
++	add	r4,r4,r3
++	add	r8,r8,r3
++	ldr	r2,[sp,#5*4]	@ 20
++	ldr	r12,[sp,#2*4]
++	ldr	r3,[sp,#4*4]
++	ldr	r1,[sp,#13*4]
++	mov	r0,r2,ror#7
++	eor	r0,r0,r2,ror#18
++	eor	r0,r0,r2,lsr#3	@ sigma0(X[i+1])
++	mov	r2,r12,ror#17
++	eor	r2,r2,r12,ror#19
++	eor	r2,r2,r12,lsr#10	@ sigma1(X[i+14])
++	add	r3,r3,r0
++	add	r3,r3,r2
++	add	r3,r3,r1
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#4*4]
++	mov	r0,r4,ror#6
++	eor	r0,r0,r4,ror#11
++	eor	r0,r0,r4,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r5,r6
++	and	r2,r2,r4
++	eor	r2,r2,r6			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r7
++	add	r3,r3,r12
++	mov	r7,r8,ror#2
++	eor	r7,r7,r8,ror#13
++	eor	r7,r7,r8,ror#22		@ Sigma0(a)
++	orr	r0,r8,r9
++	and	r0,r0,r10
++	and	r2,r8,r9
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r7,r7,r0
++	add	r11,r11,r3
++	add	r7,r7,r3
++	ldr	r2,[sp,#6*4]	@ 21
++	ldr	r12,[sp,#3*4]
++	ldr	r3,[sp,#5*4]
++	ldr	r1,[sp,#14*4]
++	mov	r0,r2,ror#7
++	eor	r0,r0,r2,ror#18
++	eor	r0,r0,r2,lsr#3	@ sigma0(X[i+1])
++	mov	r2,r12,ror#17
++	eor	r2,r2,r12,ror#19
++	eor	r2,r2,r12,lsr#10	@ sigma1(X[i+14])
++	add	r3,r3,r0
++	add	r3,r3,r2
++	add	r3,r3,r1
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#5*4]
++	mov	r0,r11,ror#6
++	eor	r0,r0,r11,ror#11
++	eor	r0,r0,r11,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r4,r5
++	and	r2,r2,r11
++	eor	r2,r2,r5			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r6
++	add	r3,r3,r12
++	mov	r6,r7,ror#2
++	eor	r6,r6,r7,ror#13
++	eor	r6,r6,r7,ror#22		@ Sigma0(a)
++	orr	r0,r7,r8
++	and	r0,r0,r9
++	and	r2,r7,r8
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r6,r6,r0
++	add	r10,r10,r3
++	add	r6,r6,r3
++	ldr	r2,[sp,#7*4]	@ 22
++	ldr	r12,[sp,#4*4]
++	ldr	r3,[sp,#6*4]
++	ldr	r1,[sp,#15*4]
++	mov	r0,r2,ror#7
++	eor	r0,r0,r2,ror#18
++	eor	r0,r0,r2,lsr#3	@ sigma0(X[i+1])
++	mov	r2,r12,ror#17
++	eor	r2,r2,r12,ror#19
++	eor	r2,r2,r12,lsr#10	@ sigma1(X[i+14])
++	add	r3,r3,r0
++	add	r3,r3,r2
++	add	r3,r3,r1
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#6*4]
++	mov	r0,r10,ror#6
++	eor	r0,r0,r10,ror#11
++	eor	r0,r0,r10,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r11,r4
++	and	r2,r2,r10
++	eor	r2,r2,r4			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r5
++	add	r3,r3,r12
++	mov	r5,r6,ror#2
++	eor	r5,r5,r6,ror#13
++	eor	r5,r5,r6,ror#22		@ Sigma0(a)
++	orr	r0,r6,r7
++	and	r0,r0,r8
++	and	r2,r6,r7
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r5,r5,r0
++	add	r9,r9,r3
++	add	r5,r5,r3
++	ldr	r2,[sp,#8*4]	@ 23
++	ldr	r12,[sp,#5*4]
++	ldr	r3,[sp,#7*4]
++	ldr	r1,[sp,#0*4]
++	mov	r0,r2,ror#7
++	eor	r0,r0,r2,ror#18
++	eor	r0,r0,r2,lsr#3	@ sigma0(X[i+1])
++	mov	r2,r12,ror#17
++	eor	r2,r2,r12,ror#19
++	eor	r2,r2,r12,lsr#10	@ sigma1(X[i+14])
++	add	r3,r3,r0
++	add	r3,r3,r2
++	add	r3,r3,r1
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#7*4]
++	mov	r0,r9,ror#6
++	eor	r0,r0,r9,ror#11
++	eor	r0,r0,r9,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r10,r11
++	and	r2,r2,r9
++	eor	r2,r2,r11			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r4
++	add	r3,r3,r12
++	mov	r4,r5,ror#2
++	eor	r4,r4,r5,ror#13
++	eor	r4,r4,r5,ror#22		@ Sigma0(a)
++	orr	r0,r5,r6
++	and	r0,r0,r7
++	and	r2,r5,r6
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r4,r4,r0
++	add	r8,r8,r3
++	add	r4,r4,r3
++	ldr	r2,[sp,#9*4]	@ 24
++	ldr	r12,[sp,#6*4]
++	ldr	r3,[sp,#8*4]
++	ldr	r1,[sp,#1*4]
++	mov	r0,r2,ror#7
++	eor	r0,r0,r2,ror#18
++	eor	r0,r0,r2,lsr#3	@ sigma0(X[i+1])
++	mov	r2,r12,ror#17
++	eor	r2,r2,r12,ror#19
++	eor	r2,r2,r12,lsr#10	@ sigma1(X[i+14])
++	add	r3,r3,r0
++	add	r3,r3,r2
++	add	r3,r3,r1
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#8*4]
++	mov	r0,r8,ror#6
++	eor	r0,r0,r8,ror#11
++	eor	r0,r0,r8,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r9,r10
++	and	r2,r2,r8
++	eor	r2,r2,r10			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r11
++	add	r3,r3,r12
++	mov	r11,r4,ror#2
++	eor	r11,r11,r4,ror#13
++	eor	r11,r11,r4,ror#22		@ Sigma0(a)
++	orr	r0,r4,r5
++	and	r0,r0,r6
++	and	r2,r4,r5
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r11,r11,r0
++	add	r7,r7,r3
++	add	r11,r11,r3
++	ldr	r2,[sp,#10*4]	@ 25
++	ldr	r12,[sp,#7*4]
++	ldr	r3,[sp,#9*4]
++	ldr	r1,[sp,#2*4]
++	mov	r0,r2,ror#7
++	eor	r0,r0,r2,ror#18
++	eor	r0,r0,r2,lsr#3	@ sigma0(X[i+1])
++	mov	r2,r12,ror#17
++	eor	r2,r2,r12,ror#19
++	eor	r2,r2,r12,lsr#10	@ sigma1(X[i+14])
++	add	r3,r3,r0
++	add	r3,r3,r2
++	add	r3,r3,r1
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#9*4]
++	mov	r0,r7,ror#6
++	eor	r0,r0,r7,ror#11
++	eor	r0,r0,r7,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r8,r9
++	and	r2,r2,r7
++	eor	r2,r2,r9			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r10
++	add	r3,r3,r12
++	mov	r10,r11,ror#2
++	eor	r10,r10,r11,ror#13
++	eor	r10,r10,r11,ror#22		@ Sigma0(a)
++	orr	r0,r11,r4
++	and	r0,r0,r5
++	and	r2,r11,r4
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r10,r10,r0
++	add	r6,r6,r3
++	add	r10,r10,r3
++	ldr	r2,[sp,#11*4]	@ 26
++	ldr	r12,[sp,#8*4]
++	ldr	r3,[sp,#10*4]
++	ldr	r1,[sp,#3*4]
++	mov	r0,r2,ror#7
++	eor	r0,r0,r2,ror#18
++	eor	r0,r0,r2,lsr#3	@ sigma0(X[i+1])
++	mov	r2,r12,ror#17
++	eor	r2,r2,r12,ror#19
++	eor	r2,r2,r12,lsr#10	@ sigma1(X[i+14])
++	add	r3,r3,r0
++	add	r3,r3,r2
++	add	r3,r3,r1
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#10*4]
++	mov	r0,r6,ror#6
++	eor	r0,r0,r6,ror#11
++	eor	r0,r0,r6,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r7,r8
++	and	r2,r2,r6
++	eor	r2,r2,r8			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r9
++	add	r3,r3,r12
++	mov	r9,r10,ror#2
++	eor	r9,r9,r10,ror#13
++	eor	r9,r9,r10,ror#22		@ Sigma0(a)
++	orr	r0,r10,r11
++	and	r0,r0,r4
++	and	r2,r10,r11
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r9,r9,r0
++	add	r5,r5,r3
++	add	r9,r9,r3
++	ldr	r2,[sp,#12*4]	@ 27
++	ldr	r12,[sp,#9*4]
++	ldr	r3,[sp,#11*4]
++	ldr	r1,[sp,#4*4]
++	mov	r0,r2,ror#7
++	eor	r0,r0,r2,ror#18
++	eor	r0,r0,r2,lsr#3	@ sigma0(X[i+1])
++	mov	r2,r12,ror#17
++	eor	r2,r2,r12,ror#19
++	eor	r2,r2,r12,lsr#10	@ sigma1(X[i+14])
++	add	r3,r3,r0
++	add	r3,r3,r2
++	add	r3,r3,r1
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#11*4]
++	mov	r0,r5,ror#6
++	eor	r0,r0,r5,ror#11
++	eor	r0,r0,r5,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r6,r7
++	and	r2,r2,r5
++	eor	r2,r2,r7			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r8
++	add	r3,r3,r12
++	mov	r8,r9,ror#2
++	eor	r8,r8,r9,ror#13
++	eor	r8,r8,r9,ror#22		@ Sigma0(a)
++	orr	r0,r9,r10
++	and	r0,r0,r11
++	and	r2,r9,r10
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r8,r8,r0
++	add	r4,r4,r3
++	add	r8,r8,r3
++	ldr	r2,[sp,#13*4]	@ 28
++	ldr	r12,[sp,#10*4]
++	ldr	r3,[sp,#12*4]
++	ldr	r1,[sp,#5*4]
++	mov	r0,r2,ror#7
++	eor	r0,r0,r2,ror#18
++	eor	r0,r0,r2,lsr#3	@ sigma0(X[i+1])
++	mov	r2,r12,ror#17
++	eor	r2,r2,r12,ror#19
++	eor	r2,r2,r12,lsr#10	@ sigma1(X[i+14])
++	add	r3,r3,r0
++	add	r3,r3,r2
++	add	r3,r3,r1
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#12*4]
++	mov	r0,r4,ror#6
++	eor	r0,r0,r4,ror#11
++	eor	r0,r0,r4,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r5,r6
++	and	r2,r2,r4
++	eor	r2,r2,r6			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r7
++	add	r3,r3,r12
++	mov	r7,r8,ror#2
++	eor	r7,r7,r8,ror#13
++	eor	r7,r7,r8,ror#22		@ Sigma0(a)
++	orr	r0,r8,r9
++	and	r0,r0,r10
++	and	r2,r8,r9
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r7,r7,r0
++	add	r11,r11,r3
++	add	r7,r7,r3
++	ldr	r2,[sp,#14*4]	@ 29
++	ldr	r12,[sp,#11*4]
++	ldr	r3,[sp,#13*4]
++	ldr	r1,[sp,#6*4]
++	mov	r0,r2,ror#7
++	eor	r0,r0,r2,ror#18
++	eor	r0,r0,r2,lsr#3	@ sigma0(X[i+1])
++	mov	r2,r12,ror#17
++	eor	r2,r2,r12,ror#19
++	eor	r2,r2,r12,lsr#10	@ sigma1(X[i+14])
++	add	r3,r3,r0
++	add	r3,r3,r2
++	add	r3,r3,r1
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#13*4]
++	mov	r0,r11,ror#6
++	eor	r0,r0,r11,ror#11
++	eor	r0,r0,r11,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r4,r5
++	and	r2,r2,r11
++	eor	r2,r2,r5			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r6
++	add	r3,r3,r12
++	mov	r6,r7,ror#2
++	eor	r6,r6,r7,ror#13
++	eor	r6,r6,r7,ror#22		@ Sigma0(a)
++	orr	r0,r7,r8
++	and	r0,r0,r9
++	and	r2,r7,r8
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r6,r6,r0
++	add	r10,r10,r3
++	add	r6,r6,r3
++	ldr	r2,[sp,#15*4]	@ 30
++	ldr	r12,[sp,#12*4]
++	ldr	r3,[sp,#14*4]
++	ldr	r1,[sp,#7*4]
++	mov	r0,r2,ror#7
++	eor	r0,r0,r2,ror#18
++	eor	r0,r0,r2,lsr#3	@ sigma0(X[i+1])
++	mov	r2,r12,ror#17
++	eor	r2,r2,r12,ror#19
++	eor	r2,r2,r12,lsr#10	@ sigma1(X[i+14])
++	add	r3,r3,r0
++	add	r3,r3,r2
++	add	r3,r3,r1
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#14*4]
++	mov	r0,r10,ror#6
++	eor	r0,r0,r10,ror#11
++	eor	r0,r0,r10,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r11,r4
++	and	r2,r2,r10
++	eor	r2,r2,r4			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r5
++	add	r3,r3,r12
++	mov	r5,r6,ror#2
++	eor	r5,r5,r6,ror#13
++	eor	r5,r5,r6,ror#22		@ Sigma0(a)
++	orr	r0,r6,r7
++	and	r0,r0,r8
++	and	r2,r6,r7
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r5,r5,r0
++	add	r9,r9,r3
++	add	r5,r5,r3
++	ldr	r2,[sp,#0*4]	@ 31
++	ldr	r12,[sp,#13*4]
++	ldr	r3,[sp,#15*4]
++	ldr	r1,[sp,#8*4]
++	mov	r0,r2,ror#7
++	eor	r0,r0,r2,ror#18
++	eor	r0,r0,r2,lsr#3	@ sigma0(X[i+1])
++	mov	r2,r12,ror#17
++	eor	r2,r2,r12,ror#19
++	eor	r2,r2,r12,lsr#10	@ sigma1(X[i+14])
++	add	r3,r3,r0
++	add	r3,r3,r2
++	add	r3,r3,r1
++	ldr	r12,[r14],#4			@ *K256++
++	str	r3,[sp,#15*4]
++	mov	r0,r9,ror#6
++	eor	r0,r0,r9,ror#11
++	eor	r0,r0,r9,ror#25	@ Sigma1(e)
++	add	r3,r3,r0
++	eor	r2,r10,r11
++	and	r2,r2,r9
++	eor	r2,r2,r11			@ Ch(e,f,g)
++	add	r3,r3,r2
++	add	r3,r3,r4
++	add	r3,r3,r12
++	mov	r4,r5,ror#2
++	eor	r4,r4,r5,ror#13
++	eor	r4,r4,r5,ror#22		@ Sigma0(a)
++	orr	r0,r5,r6
++	and	r0,r0,r7
++	and	r2,r5,r6
++	orr	r0,r0,r2			@ Maj(a,b,c)
++	add	r4,r4,r0
++	add	r8,r8,r3
++	add	r4,r4,r3
++	and	r12,r12,#0xff
++	cmp	r12,#0xf2
++	bne	.Lrounds_16_xx
++
++	ldr	r3,[sp,#16*4]		@ pull ctx
++	ldr	r0,[r3,#0]
++	ldr	r2,[r3,#4]
++	ldr	r12,[r3,#8]
++	add	r4,r4,r0
++	ldr	r0,[r3,#12]
++	add	r5,r5,r2
++	ldr	r2,[r3,#16]
++	add	r6,r6,r12
++	ldr	r12,[r3,#20]
++	add	r7,r7,r0
++	ldr	r0,[r3,#24]
++	add	r8,r8,r2
++	ldr	r2,[r3,#28]
++	add	r9,r9,r12
++	ldr	r1,[sp,#17*4]		@ pull inp
++	ldr	r12,[sp,#18*4]		@ pull inp+len
++	add	r10,r10,r0
++	add	r11,r11,r2
++	stmia	r3,{r4,r5,r6,r7,r8,r9,r10,r11}
++	cmp	r1,r12
++	sub	r14,r14,#256	@ rewind Ktbl
++	bne	.Loop
++
++	add	sp,sp,#19*4	@ destroy frame
++	ldmia	sp!,{r4-r12,lr}
++	tst	lr,#1
++	moveq	pc,lr			@ be binary compatible with V4, yet
++	.word	0xe12fff1e			@ interoperable with Thumb ISA:-)
++.size   sha256_block_data_order,.-sha256_block_data_order
++.asciz  "SHA256 block transform for ARMv4, CRYPTOGAMS by <[email protected]>"
+--- /dev/null	2009-04-24 06:09:48.000000000 -0700
++++ openssl-0.9.8h/crypto/0.9.9-dev/sha/sha512-armv4.pl	2009-09-03 15:42:39.000000000 -0700
+@@ -0,0 +1,398 @@
++#!/usr/bin/env perl
++
++# ====================================================================
++# Written by Andy Polyakov <[email protected]> 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/.
++# ====================================================================
++
++# SHA512 block procedure for ARMv4. September 2007.
++
++# This code is ~4.5 (four and a half) times faster than code generated
++# by gcc 3.4 and it spends ~72 clock cycles per byte. 
++
++# Byte order [in]dependence. =========================================
++#
++# Caller is expected to maintain specific *dword* order in h[0-7],
++# namely with most significant dword at *lower* address, which is
++# reflected in below two parameters. *Byte* order within these dwords
++# in turn is whatever *native* byte order on current platform.
++$hi=0;
++$lo=4;
++# ====================================================================
++
++$output=shift;
++open STDOUT,">$output";
++
++$ctx="r0";
++$inp="r1";
++$len="r2";
++$Tlo="r3";
++$Thi="r4";
++$Alo="r5";
++$Ahi="r6";
++$Elo="r7";
++$Ehi="r8";
++$t0="r9";
++$t1="r10";
++$t2="r11";
++$t3="r12";
++############	r13 is stack pointer
++$Ktbl="r14";
++############	r15 is program counter
++
++$Aoff=8*0;
++$Boff=8*1;
++$Coff=8*2;
++$Doff=8*3;
++$Eoff=8*4;
++$Foff=8*5;
++$Goff=8*6;
++$Hoff=8*7;
++$Xoff=8*8;
++
++sub BODY_00_15() {
++my $magic = shift;
++$code.=<<___;
++	ldr	$t2,[sp,#$Hoff+0]	@ h.lo
++	ldr	$t3,[sp,#$Hoff+4]	@ h.hi
++	@ Sigma1(x)	(ROTR((x),14) ^ ROTR((x),18)  ^ ROTR((x),41))
++	@ LO		lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23
++	@ HI		hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23
++	mov	$t0,$Elo,lsr#14
++	mov	$t1,$Ehi,lsr#14
++	eor	$t0,$t0,$Ehi,lsl#18
++	eor	$t1,$t1,$Elo,lsl#18
++	eor	$t0,$t0,$Elo,lsr#18
++	eor	$t1,$t1,$Ehi,lsr#18
++	eor	$t0,$t0,$Ehi,lsl#14
++	eor	$t1,$t1,$Elo,lsl#14
++	eor	$t0,$t0,$Ehi,lsr#9
++	eor	$t1,$t1,$Elo,lsr#9
++	eor	$t0,$t0,$Elo,lsl#23
++	eor	$t1,$t1,$Ehi,lsl#23	@ Sigma1(e)
++	adds	$Tlo,$Tlo,$t0
++	adc	$Thi,$Thi,$t1		@ T += Sigma1(e)
++	adds	$Tlo,$Tlo,$t2
++	adc	$Thi,$Thi,$t3		@ T += h
++
++	ldr	$t0,[sp,#$Foff+0]	@ f.lo
++	ldr	$t1,[sp,#$Foff+4]	@ f.hi
++	ldr	$t2,[sp,#$Goff+0]	@ g.lo
++	ldr	$t3,[sp,#$Goff+4]	@ g.hi
++	str	$Elo,[sp,#$Eoff+0]
++	str	$Ehi,[sp,#$Eoff+4]
++	str	$Alo,[sp,#$Aoff+0]
++	str	$Ahi,[sp,#$Aoff+4]
++
++	eor	$t0,$t0,$t2
++	eor	$t1,$t1,$t3
++	and	$t0,$t0,$Elo
++	and	$t1,$t1,$Ehi
++	eor	$t0,$t0,$t2
++	eor	$t1,$t1,$t3		@ Ch(e,f,g)
++
++	ldr	$t2,[$Ktbl,#4]		@ K[i].lo
++	ldr	$t3,[$Ktbl,#0]		@ K[i].hi
++	ldr	$Elo,[sp,#$Doff+0]	@ d.lo
++	ldr	$Ehi,[sp,#$Doff+4]	@ d.hi
++
++	adds	$Tlo,$Tlo,$t0
++	adc	$Thi,$Thi,$t1		@ T += Ch(e,f,g)
++	adds	$Tlo,$Tlo,$t2
++	adc	$Thi,$Thi,$t3		@ T += K[i]
++	adds	$Elo,$Elo,$Tlo
++	adc	$Ehi,$Ehi,$Thi		@ d += T
++
++	and	$t0,$t2,#0xff
++	teq	$t0,#$magic
++	orreq	$Ktbl,$Ktbl,#1
++
++	ldr	$t2,[sp,#$Boff+0]	@ b.lo
++	ldr	$t3,[sp,#$Coff+0]	@ c.lo
++	@ Sigma0(x)	(ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
++	@ LO		lo>>28^hi<<4  ^ hi>>2^lo<<30 ^ hi>>7^lo<<25
++	@ HI		hi>>28^lo<<4  ^ lo>>2^hi<<30 ^ lo>>7^hi<<25
++	mov	$t0,$Alo,lsr#28
++	mov	$t1,$Ahi,lsr#28
++	eor	$t0,$t0,$Ahi,lsl#4
++	eor	$t1,$t1,$Alo,lsl#4
++	eor	$t0,$t0,$Ahi,lsr#2
++	eor	$t1,$t1,$Alo,lsr#2
++	eor	$t0,$t0,$Alo,lsl#30
++	eor	$t1,$t1,$Ahi,lsl#30
++	eor	$t0,$t0,$Ahi,lsr#7
++	eor	$t1,$t1,$Alo,lsr#7
++	eor	$t0,$t0,$Alo,lsl#25
++	eor	$t1,$t1,$Ahi,lsl#25	@ Sigma0(a)
++	adds	$Tlo,$Tlo,$t0
++	adc	$Thi,$Thi,$t1		@ T += Sigma0(a)
++
++	and	$t0,$Alo,$t2
++	orr	$Alo,$Alo,$t2
++	ldr	$t1,[sp,#$Boff+4]	@ b.hi
++	ldr	$t2,[sp,#$Coff+4]	@ c.hi
++	and	$Alo,$Alo,$t3
++	orr	$Alo,$Alo,$t0		@ Maj(a,b,c).lo
++	and	$t3,$Ahi,$t1
++	orr	$Ahi,$Ahi,$t1
++	and	$Ahi,$Ahi,$t2
++	orr	$Ahi,$Ahi,$t3		@ Maj(a,b,c).hi
++	adds	$Alo,$Alo,$Tlo
++	adc	$Ahi,$Ahi,$Thi		@ h += T
++
++	sub	sp,sp,#8
++	add	$Ktbl,$Ktbl,#8
++___
++}
++$code=<<___;
++.text
++.code	32
++.type	K512,%object
++.align	5
++K512:
++.word	0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd
++.word	0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc
++.word	0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019
++.word	0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118
++.word	0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe
++.word	0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2
++.word	0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1
++.word	0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694
++.word	0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3
++.word	0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65
++.word	0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483
++.word	0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5
++.word	0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210
++.word	0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4
++.word	0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725
++.word	0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70
++.word	0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926
++.word	0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df
++.word	0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8
++.word	0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b
++.word	0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001
++.word	0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30
++.word	0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910
++.word	0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8
++.word	0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53
++.word	0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8
++.word	0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb
++.word	0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3
++.word	0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60
++.word	0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec
++.word	0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9
++.word	0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b
++.word	0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207
++.word	0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178
++.word	0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6
++.word	0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b
++.word	0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493
++.word	0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c
++.word	0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a
++.word	0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817
++.size	K512,.-K512
++
++.global	sha512_block_data_order
++.type	sha512_block_data_order,%function
++sha512_block_data_order:
++	sub	r3,pc,#8		@ sha512_block_data_order
++	add	$len,$inp,$len,lsl#7	@ len to point at the end of inp
++	stmdb	sp!,{r4-r12,lr}
++	sub	$Ktbl,r3,#640		@ K512
++	sub	sp,sp,#9*8
++
++	ldr	$Elo,[$ctx,#$Eoff+$lo]
++	ldr	$Ehi,[$ctx,#$Eoff+$hi]
++	ldr	$t0, [$ctx,#$Goff+$lo]
++	ldr	$t1, [$ctx,#$Goff+$hi]
++	ldr	$t2, [$ctx,#$Hoff+$lo]
++	ldr	$t3, [$ctx,#$Hoff+$hi]
++.Loop:
++	str	$t0, [sp,#$Goff+0]
++	str	$t1, [sp,#$Goff+4]
++	str	$t2, [sp,#$Hoff+0]
++	str	$t3, [sp,#$Hoff+4]
++	ldr	$Alo,[$ctx,#$Aoff+$lo]
++	ldr	$Ahi,[$ctx,#$Aoff+$hi]
++	ldr	$Tlo,[$ctx,#$Boff+$lo]
++	ldr	$Thi,[$ctx,#$Boff+$hi]
++	ldr	$t0, [$ctx,#$Coff+$lo]
++	ldr	$t1, [$ctx,#$Coff+$hi]
++	ldr	$t2, [$ctx,#$Doff+$lo]
++	ldr	$t3, [$ctx,#$Doff+$hi]
++	str	$Tlo,[sp,#$Boff+0]
++	str	$Thi,[sp,#$Boff+4]
++	str	$t0, [sp,#$Coff+0]
++	str	$t1, [sp,#$Coff+4]
++	str	$t2, [sp,#$Doff+0]
++	str	$t3, [sp,#$Doff+4]
++	ldr	$Tlo,[$ctx,#$Foff+$lo]
++	ldr	$Thi,[$ctx,#$Foff+$hi]
++	str	$Tlo,[sp,#$Foff+0]
++	str	$Thi,[sp,#$Foff+4]
++
++.L00_15:
++	ldrb	$Tlo,[$inp,#7]
++	ldrb	$t0, [$inp,#6]
++	ldrb	$t1, [$inp,#5]
++	ldrb	$t2, [$inp,#4]
++	ldrb	$Thi,[$inp,#3]
++	ldrb	$t3, [$inp,#2]
++	orr	$Tlo,$Tlo,$t0,lsl#8
++	ldrb	$t0, [$inp,#1]
++	orr	$Tlo,$Tlo,$t1,lsl#16
++	ldrb	$t1, [$inp],#8
++	orr	$Tlo,$Tlo,$t2,lsl#24
++	orr	$Thi,$Thi,$t3,lsl#8
++	orr	$Thi,$Thi,$t0,lsl#16
++	orr	$Thi,$Thi,$t1,lsl#24
++	str	$Tlo,[sp,#$Xoff+0]
++	str	$Thi,[sp,#$Xoff+4]
++___
++	&BODY_00_15(0x94);
++$code.=<<___;
++	tst	$Ktbl,#1
++	beq	.L00_15
++	bic	$Ktbl,$Ktbl,#1
++
++.L16_79:
++	ldr	$t0,[sp,#`$Xoff+8*(16-1)`+0]
++	ldr	$t1,[sp,#`$Xoff+8*(16-1)`+4]
++	ldr	$t2,[sp,#`$Xoff+8*(16-14)`+0]
++	ldr	$t3,[sp,#`$Xoff+8*(16-14)`+4]
++
++	@ sigma0(x)	(ROTR((x),1)  ^ ROTR((x),8)  ^ ((x)>>7))
++	@ LO		lo>>1^hi<<31  ^ lo>>8^hi<<24 ^ lo>>7^hi<<25
++	@ HI		hi>>1^lo<<31  ^ hi>>8^lo<<24 ^ hi>>7
++	mov	$Tlo,$t0,lsr#1
++	mov	$Thi,$t1,lsr#1
++	eor	$Tlo,$Tlo,$t1,lsl#31
++	eor	$Thi,$Thi,$t0,lsl#31
++	eor	$Tlo,$Tlo,$t0,lsr#8
++	eor	$Thi,$Thi,$t1,lsr#8
++	eor	$Tlo,$Tlo,$t1,lsl#24
++	eor	$Thi,$Thi,$t0,lsl#24
++	eor	$Tlo,$Tlo,$t0,lsr#7
++	eor	$Thi,$Thi,$t1,lsr#7
++	eor	$Tlo,$Tlo,$t1,lsl#25
++
++	@ sigma1(x)	(ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
++	@ LO		lo>>19^hi<<13 ^ hi>>29^lo<<3 ^ lo>>6^hi<<26
++	@ HI		hi>>19^lo<<13 ^ lo>>29^hi<<3 ^ hi>>6
++	mov	$t0,$t2,lsr#19
++	mov	$t1,$t3,lsr#19
++	eor	$t0,$t0,$t3,lsl#13
++	eor	$t1,$t1,$t2,lsl#13
++	eor	$t0,$t0,$t3,lsr#29
++	eor	$t1,$t1,$t2,lsr#29
++	eor	$t0,$t0,$t2,lsl#3
++	eor	$t1,$t1,$t3,lsl#3
++	eor	$t0,$t0,$t2,lsr#6
++	eor	$t1,$t1,$t3,lsr#6
++	eor	$t0,$t0,$t3,lsl#26
++
++	ldr	$t2,[sp,#`$Xoff+8*(16-9)`+0]
++	ldr	$t3,[sp,#`$Xoff+8*(16-9)`+4]
++	adds	$Tlo,$Tlo,$t0
++	adc	$Thi,$Thi,$t1
++
++	ldr	$t0,[sp,#`$Xoff+8*16`+0]
++	ldr	$t1,[sp,#`$Xoff+8*16`+4]
++	adds	$Tlo,$Tlo,$t2
++	adc	$Thi,$Thi,$t3
++	adds	$Tlo,$Tlo,$t0
++	adc	$Thi,$Thi,$t1
++	str	$Tlo,[sp,#$Xoff+0]
++	str	$Thi,[sp,#$Xoff+4]
++___
++	&BODY_00_15(0x17);
++$code.=<<___;
++	tst	$Ktbl,#1
++	beq	.L16_79
++	bic	$Ktbl,$Ktbl,#1
++
++	ldr	$Tlo,[sp,#$Boff+0]
++	ldr	$Thi,[sp,#$Boff+4]
++	ldr	$t0, [$ctx,#$Aoff+$lo]
++	ldr	$t1, [$ctx,#$Aoff+$hi]
++	ldr	$t2, [$ctx,#$Boff+$lo]
++	ldr	$t3, [$ctx,#$Boff+$hi]
++	adds	$t0,$Alo,$t0
++	adc	$t1,$Ahi,$t1
++	adds	$t2,$Tlo,$t2
++	adc	$t3,$Thi,$t3
++	str	$t0, [$ctx,#$Aoff+$lo]
++	str	$t1, [$ctx,#$Aoff+$hi]
++	str	$t2, [$ctx,#$Boff+$lo]
++	str	$t3, [$ctx,#$Boff+$hi]
++
++	ldr	$Alo,[sp,#$Coff+0]
++	ldr	$Ahi,[sp,#$Coff+4]
++	ldr	$Tlo,[sp,#$Doff+0]
++	ldr	$Thi,[sp,#$Doff+4]
++	ldr	$t0, [$ctx,#$Coff+$lo]
++	ldr	$t1, [$ctx,#$Coff+$hi]
++	ldr	$t2, [$ctx,#$Doff+$lo]
++	ldr	$t3, [$ctx,#$Doff+$hi]
++	adds	$t0,$Alo,$t0
++	adc	$t1,$Ahi,$t1
++	adds	$t2,$Tlo,$t2
++	adc	$t3,$Thi,$t3
++	str	$t0, [$ctx,#$Coff+$lo]
++	str	$t1, [$ctx,#$Coff+$hi]
++	str	$t2, [$ctx,#$Doff+$lo]
++	str	$t3, [$ctx,#$Doff+$hi]
++
++	ldr	$Tlo,[sp,#$Foff+0]
++	ldr	$Thi,[sp,#$Foff+4]
++	ldr	$t0, [$ctx,#$Eoff+$lo]
++	ldr	$t1, [$ctx,#$Eoff+$hi]
++	ldr	$t2, [$ctx,#$Foff+$lo]
++	ldr	$t3, [$ctx,#$Foff+$hi]
++	adds	$Elo,$Elo,$t0
++	adc	$Ehi,$Ehi,$t1
++	adds	$t2,$Tlo,$t2
++	adc	$t3,$Thi,$t3
++	str	$Elo,[$ctx,#$Eoff+$lo]
++	str	$Ehi,[$ctx,#$Eoff+$hi]
++	str	$t2, [$ctx,#$Foff+$lo]
++	str	$t3, [$ctx,#$Foff+$hi]
++
++	ldr	$Alo,[sp,#$Goff+0]
++	ldr	$Ahi,[sp,#$Goff+4]
++	ldr	$Tlo,[sp,#$Hoff+0]
++	ldr	$Thi,[sp,#$Hoff+4]
++	ldr	$t0, [$ctx,#$Goff+$lo]
++	ldr	$t1, [$ctx,#$Goff+$hi]
++	ldr	$t2, [$ctx,#$Hoff+$lo]
++	ldr	$t3, [$ctx,#$Hoff+$hi]
++	adds	$t0,$Alo,$t0
++	adc	$t1,$Ahi,$t1
++	adds	$t2,$Tlo,$t2
++	adc	$t3,$Thi,$t3
++	str	$t0, [$ctx,#$Goff+$lo]
++	str	$t1, [$ctx,#$Goff+$hi]
++	str	$t2, [$ctx,#$Hoff+$lo]
++	str	$t3, [$ctx,#$Hoff+$hi]
++
++	add	sp,sp,#640
++	sub	$Ktbl,$Ktbl,#640
++
++	teq	$inp,$len
++	bne	.Loop
++
++	add	sp,sp,#8*9		@ destroy frame
++	ldmia	sp!,{r4-r12,lr}
++	tst	lr,#1
++	moveq	pc,lr			@ be binary compatible with V4, yet
++	bx	lr			@ interoperable with Thumb ISA:-)
++.size   sha512_block_data_order,.-sha512_block_data_order
++.asciz  "SHA512 block transform for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
++___
++
++$code =~ s/\`([^\`]*)\`/eval $1/gem;
++$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;	# make it possible to compile with -march=armv4
++print $code;
++close STDOUT; # enforce flush
+--- /dev/null	2009-04-24 06:09:48.000000000 -0700
++++ openssl-0.9.8h/crypto/0.9.9-dev/sha/sha512-armv4.s	2009-09-03 15:42:39.000000000 -0700
+@@ -0,0 +1,415 @@
++.text
++.code	32
++.type	K512,%object
++.align	5
++K512:
++.word	0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd
++.word	0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc
++.word	0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019
++.word	0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118
++.word	0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe
++.word	0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2
++.word	0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1
++.word	0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694
++.word	0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3
++.word	0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65
++.word	0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483
++.word	0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5
++.word	0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210
++.word	0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4
++.word	0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725
++.word	0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70
++.word	0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926
++.word	0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df
++.word	0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8
++.word	0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b
++.word	0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001
++.word	0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30
++.word	0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910
++.word	0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8
++.word	0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53
++.word	0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8
++.word	0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb
++.word	0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3
++.word	0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60
++.word	0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec
++.word	0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9
++.word	0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b
++.word	0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207
++.word	0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178
++.word	0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6
++.word	0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b
++.word	0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493
++.word	0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c
++.word	0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a
++.word	0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817
++.size	K512,.-K512
++
++.global	sha512_block_data_order
++.type	sha512_block_data_order,%function
++sha512_block_data_order:
++	sub	r3,pc,#8		@ sha512_block_data_order
++	add	r2,r1,r2,lsl#7	@ len to point at the end of inp
++	stmdb	sp!,{r4-r12,lr}
++	sub	r14,r3,#640		@ K512
++	sub	sp,sp,#9*8
++
++	ldr	r7,[r0,#32+4]
++	ldr	r8,[r0,#32+0]
++	ldr	r9, [r0,#48+4]
++	ldr	r10, [r0,#48+0]
++	ldr	r11, [r0,#56+4]
++	ldr	r12, [r0,#56+0]
++.Loop:
++	str	r9, [sp,#48+0]
++	str	r10, [sp,#48+4]
++	str	r11, [sp,#56+0]
++	str	r12, [sp,#56+4]
++	ldr	r5,[r0,#0+4]
++	ldr	r6,[r0,#0+0]
++	ldr	r3,[r0,#8+4]
++	ldr	r4,[r0,#8+0]
++	ldr	r9, [r0,#16+4]
++	ldr	r10, [r0,#16+0]
++	ldr	r11, [r0,#24+4]
++	ldr	r12, [r0,#24+0]
++	str	r3,[sp,#8+0]
++	str	r4,[sp,#8+4]
++	str	r9, [sp,#16+0]
++	str	r10, [sp,#16+4]
++	str	r11, [sp,#24+0]
++	str	r12, [sp,#24+4]
++	ldr	r3,[r0,#40+4]
++	ldr	r4,[r0,#40+0]
++	str	r3,[sp,#40+0]
++	str	r4,[sp,#40+4]
++
++.L00_15:
++	ldrb	r3,[r1,#7]
++	ldrb	r9, [r1,#6]
++	ldrb	r10, [r1,#5]
++	ldrb	r11, [r1,#4]
++	ldrb	r4,[r1,#3]
++	ldrb	r12, [r1,#2]
++	orr	r3,r3,r9,lsl#8
++	ldrb	r9, [r1,#1]
++	orr	r3,r3,r10,lsl#16
++	ldrb	r10, [r1],#8
++	orr	r3,r3,r11,lsl#24
++	orr	r4,r4,r12,lsl#8
++	orr	r4,r4,r9,lsl#16
++	orr	r4,r4,r10,lsl#24
++	str	r3,[sp,#64+0]
++	str	r4,[sp,#64+4]
++	ldr	r11,[sp,#56+0]	@ h.lo
++	ldr	r12,[sp,#56+4]	@ h.hi
++	@ Sigma1(x)	(ROTR((x),14) ^ ROTR((x),18)  ^ ROTR((x),41))
++	@ LO		lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23
++	@ HI		hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23
++	mov	r9,r7,lsr#14
++	mov	r10,r8,lsr#14
++	eor	r9,r9,r8,lsl#18
++	eor	r10,r10,r7,lsl#18
++	eor	r9,r9,r7,lsr#18
++	eor	r10,r10,r8,lsr#18
++	eor	r9,r9,r8,lsl#14
++	eor	r10,r10,r7,lsl#14
++	eor	r9,r9,r8,lsr#9
++	eor	r10,r10,r7,lsr#9
++	eor	r9,r9,r7,lsl#23
++	eor	r10,r10,r8,lsl#23	@ Sigma1(e)
++	adds	r3,r3,r9
++	adc	r4,r4,r10		@ T += Sigma1(e)
++	adds	r3,r3,r11
++	adc	r4,r4,r12		@ T += h
++
++	ldr	r9,[sp,#40+0]	@ f.lo
++	ldr	r10,[sp,#40+4]	@ f.hi
++	ldr	r11,[sp,#48+0]	@ g.lo
++	ldr	r12,[sp,#48+4]	@ g.hi
++	str	r7,[sp,#32+0]
++	str	r8,[sp,#32+4]
++	str	r5,[sp,#0+0]
++	str	r6,[sp,#0+4]
++
++	eor	r9,r9,r11
++	eor	r10,r10,r12
++	and	r9,r9,r7
++	and	r10,r10,r8
++	eor	r9,r9,r11
++	eor	r10,r10,r12		@ Ch(e,f,g)
++
++	ldr	r11,[r14,#4]		@ K[i].lo
++	ldr	r12,[r14,#0]		@ K[i].hi
++	ldr	r7,[sp,#24+0]	@ d.lo
++	ldr	r8,[sp,#24+4]	@ d.hi
++
++	adds	r3,r3,r9
++	adc	r4,r4,r10		@ T += Ch(e,f,g)
++	adds	r3,r3,r11
++	adc	r4,r4,r12		@ T += K[i]
++	adds	r7,r7,r3
++	adc	r8,r8,r4		@ d += T
++
++	and	r9,r11,#0xff
++	teq	r9,#148
++	orreq	r14,r14,#1
++
++	ldr	r11,[sp,#8+0]	@ b.lo
++	ldr	r12,[sp,#16+0]	@ c.lo
++	@ Sigma0(x)	(ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
++	@ LO		lo>>28^hi<<4  ^ hi>>2^lo<<30 ^ hi>>7^lo<<25
++	@ HI		hi>>28^lo<<4  ^ lo>>2^hi<<30 ^ lo>>7^hi<<25
++	mov	r9,r5,lsr#28
++	mov	r10,r6,lsr#28
++	eor	r9,r9,r6,lsl#4
++	eor	r10,r10,r5,lsl#4
++	eor	r9,r9,r6,lsr#2
++	eor	r10,r10,r5,lsr#2
++	eor	r9,r9,r5,lsl#30
++	eor	r10,r10,r6,lsl#30
++	eor	r9,r9,r6,lsr#7
++	eor	r10,r10,r5,lsr#7
++	eor	r9,r9,r5,lsl#25
++	eor	r10,r10,r6,lsl#25	@ Sigma0(a)
++	adds	r3,r3,r9
++	adc	r4,r4,r10		@ T += Sigma0(a)
++
++	and	r9,r5,r11
++	orr	r5,r5,r11
++	ldr	r10,[sp,#8+4]	@ b.hi
++	ldr	r11,[sp,#16+4]	@ c.hi
++	and	r5,r5,r12
++	orr	r5,r5,r9		@ Maj(a,b,c).lo
++	and	r12,r6,r10
++	orr	r6,r6,r10
++	and	r6,r6,r11
++	orr	r6,r6,r12		@ Maj(a,b,c).hi
++	adds	r5,r5,r3
++	adc	r6,r6,r4		@ h += T
++
++	sub	sp,sp,#8
++	add	r14,r14,#8
++	tst	r14,#1
++	beq	.L00_15
++	bic	r14,r14,#1
++
++.L16_79:
++	ldr	r9,[sp,#184+0]
++	ldr	r10,[sp,#184+4]
++	ldr	r11,[sp,#80+0]
++	ldr	r12,[sp,#80+4]
++
++	@ sigma0(x)	(ROTR((x),1)  ^ ROTR((x),8)  ^ ((x)>>7))
++	@ LO		lo>>1^hi<<31  ^ lo>>8^hi<<24 ^ lo>>7^hi<<25
++	@ HI		hi>>1^lo<<31  ^ hi>>8^lo<<24 ^ hi>>7
++	mov	r3,r9,lsr#1
++	mov	r4,r10,lsr#1
++	eor	r3,r3,r10,lsl#31
++	eor	r4,r4,r9,lsl#31
++	eor	r3,r3,r9,lsr#8
++	eor	r4,r4,r10,lsr#8
++	eor	r3,r3,r10,lsl#24
++	eor	r4,r4,r9,lsl#24
++	eor	r3,r3,r9,lsr#7
++	eor	r4,r4,r10,lsr#7
++	eor	r3,r3,r10,lsl#25
++
++	@ sigma1(x)	(ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
++	@ LO		lo>>19^hi<<13 ^ hi>>29^lo<<3 ^ lo>>6^hi<<26
++	@ HI		hi>>19^lo<<13 ^ lo>>29^hi<<3 ^ hi>>6
++	mov	r9,r11,lsr#19
++	mov	r10,r12,lsr#19
++	eor	r9,r9,r12,lsl#13
++	eor	r10,r10,r11,lsl#13
++	eor	r9,r9,r12,lsr#29
++	eor	r10,r10,r11,lsr#29
++	eor	r9,r9,r11,lsl#3
++	eor	r10,r10,r12,lsl#3
++	eor	r9,r9,r11,lsr#6
++	eor	r10,r10,r12,lsr#6
++	eor	r9,r9,r12,lsl#26
++
++	ldr	r11,[sp,#120+0]
++	ldr	r12,[sp,#120+4]
++	adds	r3,r3,r9
++	adc	r4,r4,r10
++
++	ldr	r9,[sp,#192+0]
++	ldr	r10,[sp,#192+4]
++	adds	r3,r3,r11
++	adc	r4,r4,r12
++	adds	r3,r3,r9
++	adc	r4,r4,r10
++	str	r3,[sp,#64+0]
++	str	r4,[sp,#64+4]
++	ldr	r11,[sp,#56+0]	@ h.lo
++	ldr	r12,[sp,#56+4]	@ h.hi
++	@ Sigma1(x)	(ROTR((x),14) ^ ROTR((x),18)  ^ ROTR((x),41))
++	@ LO		lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23
++	@ HI		hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23
++	mov	r9,r7,lsr#14
++	mov	r10,r8,lsr#14
++	eor	r9,r9,r8,lsl#18
++	eor	r10,r10,r7,lsl#18
++	eor	r9,r9,r7,lsr#18
++	eor	r10,r10,r8,lsr#18
++	eor	r9,r9,r8,lsl#14
++	eor	r10,r10,r7,lsl#14
++	eor	r9,r9,r8,lsr#9
++	eor	r10,r10,r7,lsr#9
++	eor	r9,r9,r7,lsl#23
++	eor	r10,r10,r8,lsl#23	@ Sigma1(e)
++	adds	r3,r3,r9
++	adc	r4,r4,r10		@ T += Sigma1(e)
++	adds	r3,r3,r11
++	adc	r4,r4,r12		@ T += h
++
++	ldr	r9,[sp,#40+0]	@ f.lo
++	ldr	r10,[sp,#40+4]	@ f.hi
++	ldr	r11,[sp,#48+0]	@ g.lo
++	ldr	r12,[sp,#48+4]	@ g.hi
++	str	r7,[sp,#32+0]
++	str	r8,[sp,#32+4]
++	str	r5,[sp,#0+0]
++	str	r6,[sp,#0+4]
++
++	eor	r9,r9,r11
++	eor	r10,r10,r12
++	and	r9,r9,r7
++	and	r10,r10,r8
++	eor	r9,r9,r11
++	eor	r10,r10,r12		@ Ch(e,f,g)
++
++	ldr	r11,[r14,#4]		@ K[i].lo
++	ldr	r12,[r14,#0]		@ K[i].hi
++	ldr	r7,[sp,#24+0]	@ d.lo
++	ldr	r8,[sp,#24+4]	@ d.hi
++
++	adds	r3,r3,r9
++	adc	r4,r4,r10		@ T += Ch(e,f,g)
++	adds	r3,r3,r11
++	adc	r4,r4,r12		@ T += K[i]
++	adds	r7,r7,r3
++	adc	r8,r8,r4		@ d += T
++
++	and	r9,r11,#0xff
++	teq	r9,#23
++	orreq	r14,r14,#1
++
++	ldr	r11,[sp,#8+0]	@ b.lo
++	ldr	r12,[sp,#16+0]	@ c.lo
++	@ Sigma0(x)	(ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
++	@ LO		lo>>28^hi<<4  ^ hi>>2^lo<<30 ^ hi>>7^lo<<25
++	@ HI		hi>>28^lo<<4  ^ lo>>2^hi<<30 ^ lo>>7^hi<<25
++	mov	r9,r5,lsr#28
++	mov	r10,r6,lsr#28
++	eor	r9,r9,r6,lsl#4
++	eor	r10,r10,r5,lsl#4
++	eor	r9,r9,r6,lsr#2
++	eor	r10,r10,r5,lsr#2
++	eor	r9,r9,r5,lsl#30
++	eor	r10,r10,r6,lsl#30
++	eor	r9,r9,r6,lsr#7
++	eor	r10,r10,r5,lsr#7
++	eor	r9,r9,r5,lsl#25
++	eor	r10,r10,r6,lsl#25	@ Sigma0(a)
++	adds	r3,r3,r9
++	adc	r4,r4,r10		@ T += Sigma0(a)
++
++	and	r9,r5,r11
++	orr	r5,r5,r11
++	ldr	r10,[sp,#8+4]	@ b.hi
++	ldr	r11,[sp,#16+4]	@ c.hi
++	and	r5,r5,r12
++	orr	r5,r5,r9		@ Maj(a,b,c).lo
++	and	r12,r6,r10
++	orr	r6,r6,r10
++	and	r6,r6,r11
++	orr	r6,r6,r12		@ Maj(a,b,c).hi
++	adds	r5,r5,r3
++	adc	r6,r6,r4		@ h += T
++
++	sub	sp,sp,#8
++	add	r14,r14,#8
++	tst	r14,#1
++	beq	.L16_79
++	bic	r14,r14,#1
++
++	ldr	r3,[sp,#8+0]
++	ldr	r4,[sp,#8+4]
++	ldr	r9, [r0,#0+4]
++	ldr	r10, [r0,#0+0]
++	ldr	r11, [r0,#8+4]
++	ldr	r12, [r0,#8+0]
++	adds	r9,r5,r9
++	adc	r10,r6,r10
++	adds	r11,r3,r11
++	adc	r12,r4,r12
++	str	r9, [r0,#0+4]
++	str	r10, [r0,#0+0]
++	str	r11, [r0,#8+4]
++	str	r12, [r0,#8+0]
++
++	ldr	r5,[sp,#16+0]
++	ldr	r6,[sp,#16+4]
++	ldr	r3,[sp,#24+0]
++	ldr	r4,[sp,#24+4]
++	ldr	r9, [r0,#16+4]
++	ldr	r10, [r0,#16+0]
++	ldr	r11, [r0,#24+4]
++	ldr	r12, [r0,#24+0]
++	adds	r9,r5,r9
++	adc	r10,r6,r10
++	adds	r11,r3,r11
++	adc	r12,r4,r12
++	str	r9, [r0,#16+4]
++	str	r10, [r0,#16+0]
++	str	r11, [r0,#24+4]
++	str	r12, [r0,#24+0]
++
++	ldr	r3,[sp,#40+0]
++	ldr	r4,[sp,#40+4]
++	ldr	r9, [r0,#32+4]
++	ldr	r10, [r0,#32+0]
++	ldr	r11, [r0,#40+4]
++	ldr	r12, [r0,#40+0]
++	adds	r7,r7,r9
++	adc	r8,r8,r10
++	adds	r11,r3,r11
++	adc	r12,r4,r12
++	str	r7,[r0,#32+4]
++	str	r8,[r0,#32+0]
++	str	r11, [r0,#40+4]
++	str	r12, [r0,#40+0]
++
++	ldr	r5,[sp,#48+0]
++	ldr	r6,[sp,#48+4]
++	ldr	r3,[sp,#56+0]
++	ldr	r4,[sp,#56+4]
++	ldr	r9, [r0,#48+4]
++	ldr	r10, [r0,#48+0]
++	ldr	r11, [r0,#56+4]
++	ldr	r12, [r0,#56+0]
++	adds	r9,r5,r9
++	adc	r10,r6,r10
++	adds	r11,r3,r11
++	adc	r12,r4,r12
++	str	r9, [r0,#48+4]
++	str	r10, [r0,#48+0]
++	str	r11, [r0,#56+4]
++	str	r12, [r0,#56+0]
++
++	add	sp,sp,#640
++	sub	r14,r14,#640
++
++	teq	r1,r2
++	bne	.Loop
++
++	add	sp,sp,#8*9		@ destroy frame
++	ldmia	sp!,{r4-r12,lr}
++	tst	lr,#1
++	moveq	pc,lr			@ be binary compatible with V4, yet
++	.word	0xe12fff1e			@ interoperable with Thumb ISA:-)
++.size   sha512_block_data_order,.-sha512_block_data_order
++.asciz  "SHA512 block transform for ARMv4, CRYPTOGAMS by <[email protected]>"
diff --git a/patches/crypto_Android.mk b/patches/crypto_Android.mk
new file mode 100644
index 0000000..e92f0d1
--- /dev/null
+++ b/patches/crypto_Android.mk
@@ -0,0 +1,441 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+ifeq ($(TARGET_ARCH),arm)
+	LOCAL_CFLAGS += -DOPENSSL_BN_ASM_MONT -DAES_ASM -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM
+	LOCAL_SRC_FILES:= 0.9.9-dev/bn/armv4-mont.s \
+	                  0.9.9-dev/aes/aes-armv4.s \
+	                  0.9.9-dev/sha/sha1-armv4-large.s \
+	                  0.9.9-dev/sha/sha256-armv4.s \
+	                  0.9.9-dev/sha/sha512-armv4.s
+else
+	LOCAL_SRC_FILES:= aes/aes_core.c
+endif
+
+LOCAL_SRC_FILES+= \
+	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 \
+	aes/aes_misc.c \
+	aes/aes_ecb.c \
+	aes/aes_cbc.c \
+	aes/aes_cfb.c \
+	aes/aes_ofb.c \
+	aes/aes_ctr.c \
+	aes/aes_wrap.c \
+	asn1/a_object.c \
+	asn1/a_bitstr.c \
+	asn1/a_utctm.c \
+	asn1/a_gentm.c \
+	asn1/a_time.c \
+	asn1/a_int.c \
+	asn1/a_octet.c \
+	asn1/a_print.c \
+	asn1/a_type.c \
+	asn1/a_set.c \
+	asn1/a_dup.c \
+	asn1/a_d2i_fp.c \
+	asn1/a_i2d_fp.c \
+	asn1/a_enum.c \
+	asn1/a_utf8.c \
+	asn1/a_sign.c \
+	asn1/a_digest.c \
+	asn1/a_verify.c \
+	asn1/a_mbstr.c \
+	asn1/a_strex.c \
+	asn1/x_algor.c \
+	asn1/x_val.c \
+	asn1/x_pubkey.c \
+	asn1/x_sig.c \
+	asn1/x_req.c \
+	asn1/x_attrib.c \
+	asn1/x_bignum.c \
+	asn1/x_long.c \
+	asn1/x_name.c \
+	asn1/x_x509.c \
+	asn1/x_x509a.c \
+	asn1/x_crl.c \
+	asn1/x_info.c \
+	asn1/x_spki.c \
+	asn1/nsseq.c \
+	asn1/d2i_pu.c \
+	asn1/d2i_pr.c \
+	asn1/i2d_pu.c \
+	asn1/i2d_pr.c \
+	asn1/t_req.c \
+	asn1/t_x509.c \
+	asn1/t_x509a.c \
+	asn1/t_crl.c \
+	asn1/t_pkey.c \
+	asn1/t_spki.c \
+	asn1/t_bitst.c \
+	asn1/tasn_new.c \
+	asn1/tasn_fre.c \
+	asn1/tasn_enc.c \
+	asn1/tasn_dec.c \
+	asn1/tasn_utl.c \
+	asn1/tasn_typ.c \
+	asn1/f_int.c \
+	asn1/f_string.c \
+	asn1/n_pkey.c \
+	asn1/f_enum.c \
+	asn1/a_hdr.c \
+	asn1/x_pkey.c \
+	asn1/a_bool.c \
+	asn1/x_exten.c \
+	asn1/asn1_par.c \
+	asn1/asn1_lib.c \
+	asn1/asn1_err.c \
+	asn1/a_meth.c \
+	asn1/a_bytes.c \
+	asn1/a_strnid.c \
+	asn1/evp_asn1.c \
+	asn1/asn_pack.c \
+	asn1/p5_pbe.c \
+	asn1/p5_pbev2.c \
+	asn1/p8_pkey.c \
+	asn1/asn_moid.c \
+	asn1/asn1_gen.c \
+	asn1/asn_mime.c \
+	bio/bio_lib.c \
+	bio/bio_cb.c \
+	bio/bio_err.c \
+	bio/bss_mem.c \
+	bio/bss_null.c \
+	bio/bss_fd.c \
+	bio/bss_file.c \
+	bio/bss_sock.c \
+	bio/bss_conn.c \
+	bio/bf_null.c \
+	bio/bf_buff.c \
+	bio/b_print.c \
+	bio/b_dump.c \
+	bio/b_sock.c \
+	bio/bss_acpt.c \
+	bio/bf_nbio.c \
+	bio/bss_log.c \
+	bio/bss_bio.c \
+	bio/bss_dgram.c \
+	bn/bn_add.c \
+	bn/bn_div.c \
+	bn/bn_exp.c \
+	bn/bn_lib.c \
+	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 \
+	bn/bn_word.c \
+	bn/bn_blind.c \
+	bn/bn_kron.c \
+	bn/bn_sqrt.c \
+	bn/bn_gcd.c \
+	bn/bn_prime.c \
+	bn/bn_err.c \
+	bn/bn_sqr.c \
+	bn/bn_asm.c \
+	bn/bn_recp.c \
+	bn/bn_mont.c \
+	bn/bn_mpi.c \
+	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 \
+	comp/c_zlib.c \
+	conf/conf_err.c \
+	conf/conf_lib.c \
+	conf/conf_api.c \
+	conf/conf_def.c \
+	conf/conf_mod.c \
+	conf/conf_mall.c \
+	conf/conf_sap.c \
+	des/cbc_cksm.c \
+	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 \
+	des/enc_writ.c \
+	des/fcrypt.c \
+	des/ofb64enc.c \
+	des/ofb_enc.c \
+	des/pcbc_enc.c \
+	des/qud_cksm.c \
+	des/rand_key.c \
+	des/rpc_enc.c \
+	des/set_key.c \
+	des/des_enc.c \
+	des/fcrypt_b.c \
+	des/xcbc_enc.c \
+	des/str2key.c \
+	des/cfb64ede.c \
+	des/ofb64ede.c \
+	des/ede_cbcm_enc.c \
+	des/des_old.c \
+	des/des_old2.c \
+	des/read2pwd.c \
+	dso/dso_dl.c \
+	dso/dso_dlfcn.c \
+	dso/dso_err.c \
+	dso/dso_lib.c \
+	dso/dso_null.c \
+	dso/dso_openssl.c \
+	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 \
+	evp/e_des.c \
+	evp/e_des3.c \
+	evp/e_rc4.c \
+	evp/e_aes.c \
+	evp/names.c \
+	evp/e_xcbc_d.c \
+	evp/e_rc2.c \
+	evp/e_rc5.c \
+	evp/m_null.c \
+	evp/m_md2.c \
+	evp/m_md4.c \
+	evp/m_md5.c \
+	evp/m_sha.c \
+	evp/m_sha1.c \
+	evp/m_dss.c \
+	evp/m_dss1.c \
+	evp/m_mdc2.c \
+	evp/p_open.c \
+	evp/p_seal.c \
+	evp/p_sign.c \
+	evp/p_verify.c \
+	evp/p_lib.c \
+	evp/p_enc.c \
+	evp/p_dec.c \
+	evp/bio_md.c \
+	evp/bio_b64.c \
+	evp/bio_enc.c \
+	evp/evp_err.c \
+	evp/e_null.c \
+	evp/c_all.c \
+	evp/c_allc.c \
+	evp/c_alld.c \
+	evp/evp_lib.c \
+	evp/bio_ok.c \
+	evp/evp_pkey.c \
+	evp/evp_pbe.c \
+	evp/p5_crpt.c \
+	evp/p5_crpt2.c \
+	evp/e_old.c \
+	hmac/hmac.c \
+	krb5/krb5_asn.c \
+	lhash/lhash.c \
+	lhash/lh_stats.c \
+	md4/md4_dgst.c \
+	md4/md4_one.c \
+	md5/md5_dgst.c \
+	md5/md5_one.c \
+	objects/o_names.c \
+	objects/obj_dat.c \
+	objects/obj_lib.c \
+	objects/obj_err.c \
+	pem/pem_sign.c \
+	pem/pem_seal.c \
+	pem/pem_info.c \
+	pem/pem_lib.c \
+	pem/pem_all.c \
+	pem/pem_err.c \
+	pem/pem_x509.c \
+	pem/pem_xaux.c \
+	pem/pem_oth.c \
+	pem/pem_pk8.c \
+	pem/pem_pkey.c \
+	pkcs12/p12_add.c \
+	pkcs12/p12_asn.c \
+	pkcs12/p12_attr.c \
+	pkcs12/p12_crpt.c \
+	pkcs12/p12_crt.c \
+	pkcs12/p12_decr.c \
+	pkcs12/p12_init.c \
+	pkcs12/p12_key.c \
+	pkcs12/p12_kiss.c \
+	pkcs12/p12_mutl.c \
+	pkcs12/p12_utl.c \
+	pkcs12/p12_npas.c \
+	pkcs12/pk12err.c \
+	pkcs12/p12_p8d.c \
+	pkcs12/p12_p8e.c \
+	pkcs7/pk7_asn1.c \
+	pkcs7/pk7_lib.c \
+	pkcs7/pkcs7err.c \
+	pkcs7/pk7_doit.c \
+	pkcs7/pk7_smime.c \
+	pkcs7/pk7_attr.c \
+	pkcs7/pk7_mime.c \
+	rand/md_rand.c \
+	rand/randfile.c \
+	rand/rand_lib.c \
+	rand/rand_err.c \
+	rand/rand_egd.c \
+	rand/rand_unix.c \
+	rc2/rc2_ecb.c \
+	rc2/rc2_skey.c \
+	rc2/rc2_cbc.c \
+	rc2/rc2cfb64.c \
+	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 \
+	rsa/rsa_saos.c \
+	rsa/rsa_err.c \
+	rsa/rsa_pk1.c \
+	rsa/rsa_ssl.c \
+	rsa/rsa_none.c \
+	rsa/rsa_oaep.c \
+	rsa/rsa_chk.c \
+	rsa/rsa_null.c \
+	rsa/rsa_pss.c \
+	rsa/rsa_x931.c \
+	rsa/rsa_asn1.c \
+	sha/sha_dgst.c \
+	sha/sha1dgst.c \
+	sha/sha_one.c \
+	sha/sha1_one.c \
+	sha/sha256.c \
+	sha/sha512.c \
+	stack/stack.c \
+	txt_db/txt_db.c \
+	ui/ui_err.c \
+	ui/ui_lib.c \
+	ui/ui_openssl.c \
+	ui/ui_util.c \
+	ui/ui_compat.c \
+	x509/x509_def.c \
+	x509/x509_d2.c \
+	x509/x509_r2x.c \
+	x509/x509_cmp.c \
+	x509/x509_obj.c \
+	x509/x509_req.c \
+	x509/x509spki.c \
+	x509/x509_vfy.c \
+	x509/x509_set.c \
+	x509/x509cset.c \
+	x509/x509rset.c \
+	x509/x509_err.c \
+	x509/x509name.c \
+	x509/x509_v3.c \
+	x509/x509_ext.c \
+	x509/x509_att.c \
+	x509/x509_vpm.c \
+	x509/x509type.c \
+	x509/x509_lu.c \
+	x509/x_all.c \
+	x509/x509_txt.c \
+	x509/x509_trs.c \
+	x509/by_file.c \
+	x509/by_dir.c \
+	x509v3/v3_bcons.c \
+	x509v3/v3_bitst.c \
+	x509v3/v3_conf.c \
+	x509v3/v3_extku.c \
+	x509v3/v3_ia5.c \
+	x509v3/v3_lib.c \
+	x509v3/v3_prn.c \
+	x509v3/v3_utl.c \
+	x509v3/v3err.c \
+	x509v3/v3_genn.c \
+	x509v3/v3_alt.c \
+	x509v3/v3_skey.c \
+	x509v3/v3_akey.c \
+	x509v3/v3_pku.c \
+	x509v3/v3_int.c \
+	x509v3/v3_enum.c \
+	x509v3/v3_sxnet.c \
+	x509v3/v3_cpols.c \
+	x509v3/v3_crld.c \
+	x509v3/v3_purp.c \
+	x509v3/v3_info.c \
+	x509v3/v3_akeya.c \
+	x509v3/v3_pcia.c \
+	x509v3/v3_pci.c \
+	x509v3/v3_pmaps.c \
+	x509v3/v3_pcons.c \
+	x509v3/v3_ncons.c \
+	x509v3/pcy_lib.c \
+	x509v3/pcy_cache.c \
+	x509v3/pcy_node.c \
+	x509v3/pcy_map.c \
+	x509v3/pcy_data.c \
+	x509v3/pcy_tree.c \
+	dh/dh_asn1.c \
+	dh/dh_check.c \
+	dh/dh_depr.c \
+	dh/dh_err.c \
+	dh/dh_gen.c \
+	dh/dh_key.c \
+	dh/dh_lib.c \
+	dsa/dsa_asn1.c \
+	dsa/dsa_depr.c \
+	dsa/dsa_err.c \
+	dsa/dsa_gen.c \
+	dsa/dsa_key.c \
+	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 \
+	evp/m_ripemd.c
+
+LOCAL_CFLAGS += -DNO_WINDOWS_BRAINDEATH 
+
+include $(LOCAL_PATH)/../android-config.mk
+
+LOCAL_C_INCLUDES += \
+	external/openssl \
+	external/openssl/include \
+
+# LOCAL_SHARED_LIBRARIES += libengines
+
+ifneq ($(TARGET_SIMULATOR),true)
+	LOCAL_SHARED_LIBRARIES += libdl
+endif
+
+LOCAL_LDLIBS += -ldl
+
+LOCAL_MODULE:= libcrypto
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/patches/openssl_defs.patch b/patches/openssl_defs.patch
new file mode 100644
index 0000000..d2c54d6
--- /dev/null
+++ b/patches/openssl_defs.patch
@@ -0,0 +1,12 @@
+--- openssl-0.9.8k.orig/crypto/err/err_all.c	2008-11-24 08:14:14.000000000 -0800
++++ openssl-0.9.8k/crypto/err/err_all.c	2009-09-29 14:23:15.000000000 -0700
+@@ -146,7 +146,9 @@ void ERR_load_crypto_strings(void)
+ #ifndef OPENSSL_NO_ENGINE
+ 	ERR_load_ENGINE_strings();
+ #endif
++#ifndef OPENSSL_NO_OCSP
+ 	ERR_load_OCSP_strings();
++#endif
+ 	ERR_load_UI_strings();
+ #ifdef OPENSSL_FIPS
+ 	ERR_load_FIPS_strings();
diff --git a/patches/progs.patch b/patches/progs.patch
new file mode 100644
index 0000000..d8249e6
--- /dev/null
+++ b/patches/progs.patch
@@ -0,0 +1,78 @@
+diff -uarp openssl-0.9.8k.orig/apps/progs.h openssl-0.9.8k/apps/progs.h
+--- openssl-0.9.8k.orig/apps/progs.h	2008-04-03 16:03:41.000000000 -0700
++++ openssl-0.9.8k/apps/progs.h	2009-09-29 18:07:01.000000000 -0700
+@@ -22,7 +22,9 @@ extern int ecparam_main(int argc,char *a
+ extern int x509_main(int argc,char *argv[]);
+ extern int genrsa_main(int argc,char *argv[]);
+ extern int gendsa_main(int argc,char *argv[]);
++#if 0 /* ANDROID */
+ extern int s_server_main(int argc,char *argv[]);
++#endif
+ extern int s_client_main(int argc,char *argv[]);
+ extern int speed_main(int argc,char *argv[]);
+ extern int s_time_main(int argc,char *argv[]);
+@@ -39,7 +41,9 @@ extern int spkac_main(int argc,char *arg
+ extern int smime_main(int argc,char *argv[]);
+ extern int rand_main(int argc,char *argv[]);
+ extern int engine_main(int argc,char *argv[]);
++#ifndef OPENSSL_NO_OCSP
+ extern int ocsp_main(int argc,char *argv[]);
++#endif
+ extern int prime_main(int argc,char *argv[]);
+ 
+ #define FUNC_TYPE_GENERAL	1
+@@ -97,7 +101,9 @@ FUNCTION functions[] = {
+ 	{FUNC_TYPE_GENERAL,"gendsa",gendsa_main},
+ #endif
+ #if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
+-	{FUNC_TYPE_GENERAL,"s_server",s_server_main},
++#if 0 /* ANDROID */
++        {FUNC_TYPE_GENERAL,"s_server",s_server_main},
++#endif
+ #endif
+ #if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
+ 	{FUNC_TYPE_GENERAL,"s_client",s_client_main},
+@@ -129,7 +135,9 @@ FUNCTION functions[] = {
+ #ifndef OPENSSL_NO_ENGINE
+ 	{FUNC_TYPE_GENERAL,"engine",engine_main},
+ #endif
++#ifndef OPENSSL_NO_OCSP
+ 	{FUNC_TYPE_GENERAL,"ocsp",ocsp_main},
++#endif
+ 	{FUNC_TYPE_GENERAL,"prime",prime_main},
+ #ifndef OPENSSL_NO_MD2
+ 	{FUNC_TYPE_MD,"md2",dgst_main},
+diff -uarp openssl-0.9.8k.orig/apps/speed.c openssl-0.9.8k/apps/speed.c
+--- openssl-0.9.8k.orig/apps/speed.c	2009-01-07 02:48:22.000000000 -0800
++++ openssl-0.9.8k/apps/speed.c	2009-09-29 18:06:38.000000000 -0700
+@@ -108,12 +108,12 @@
+ #include <signal.h>
+ #endif
+ 
+-#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(OPENSSL_SYS_MACOSX)
++#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(OPENSSL_SYS_MACOSX) || defined(HAVE_ANDROID_OS)
+ # define USE_TOD
+ #elif !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VXWORKS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC))
+ # define TIMES
+ #endif
+-#if !defined(_UNICOS) && !defined(__OpenBSD__) && !defined(sgi) && !defined(__FreeBSD__) && !(defined(__bsdi) || defined(__bsdi__)) && !defined(_AIX) && !defined(OPENSSL_SYS_MPE) && !defined(__NetBSD__) && !defined(OPENSSL_SYS_VXWORKS) /* FIXME */
++#if !defined(_UNICOS) && !defined(__OpenBSD__) && !defined(sgi) && !defined(__FreeBSD__) && !(defined(__bsdi) || defined(__bsdi__)) && !defined(_AIX) && !defined(OPENSSL_SYS_MPE) && !defined(__NetBSD__) && !defined(OPENSSL_SYS_VXWORKS) && !defined(HAVE_ANDROID_OS) /* FIXME */
+ # define TIMEB
+ #endif
+ 
+@@ -1836,6 +1836,7 @@ int MAIN(int argc, char **argv)
+ 			}
+ 		}
+ 
++#if 0 /* ANDROID */
+ 	if (doit[D_IGE_128_AES])
+ 		{
+ 		for (j=0; j<SIZE_NUM; j++)
+@@ -1879,6 +1880,7 @@ int MAIN(int argc, char **argv)
+ 			}
+ 		}
+ #endif
++#endif
+ #ifndef OPENSSL_NO_CAMELLIA
+ 	if (doit[D_CBC_128_CML])
+ 		{
diff --git a/patches/ssl_Android.mk b/patches/ssl_Android.mk
new file mode 100644
index 0000000..75cb8a1
--- /dev/null
+++ b/patches/ssl_Android.mk
@@ -0,0 +1,54 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	s2_meth.c \
+	s2_srvr.c \
+	s2_clnt.c \
+	s2_lib.c \
+	s2_enc.c \
+	s2_pkt.c \
+	s3_meth.c \
+	s3_srvr.c \
+	s3_clnt.c \
+	s3_lib.c \
+	s3_enc.c \
+	s3_pkt.c \
+	s3_both.c \
+	s23_meth.c \
+	s23_srvr.c \
+	s23_clnt.c \
+	s23_lib.c \
+	s23_pkt.c \
+	t1_meth.c \
+	t1_srvr.c \
+	t1_clnt.c \
+	t1_lib.c \
+	t1_enc.c \
+	ssl_lib.c \
+	ssl_err2.c \
+	ssl_cert.c \
+	ssl_sess.c \
+	ssl_ciph.c \
+	ssl_stat.c \
+	ssl_rsa.c \
+	ssl_asn1.c \
+	ssl_txt.c \
+	ssl_algs.c \
+	bio_ssl.c \
+	ssl_err.c \
+	kssl.c
+
+include $(LOCAL_PATH)/../android-config.mk
+
+
+LOCAL_C_INCLUDES += \
+	external/openssl \
+	external/openssl/include \
+	external/openssl/crypto
+
+LOCAL_SHARED_LIBRARIES += libcrypto
+
+LOCAL_MODULE:= libssl
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/ssl/Makefile b/ssl/Makefile
index 2754632..46c0659 100644
--- a/ssl/Makefile
+++ b/ssl/Makefile
@@ -53,7 +53,7 @@
 top:
 	(cd ..; $(MAKE) DIRS=$(DIR) all)
 
-all:	shared
+all:	lib
 
 lib:	$(LIBOBJ)
 	$(AR) $(LIB) $(LIBOBJ)
@@ -111,7 +111,8 @@
 bio_ssl.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
 bio_ssl.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 bio_ssl.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-bio_ssl.o: ../include/openssl/evp.h ../include/openssl/kssl.h
+bio_ssl.o: ../include/openssl/evp.h ../include/openssl/fips.h
+bio_ssl.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
 bio_ssl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 bio_ssl.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
 bio_ssl.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
@@ -130,6 +131,7 @@
 d1_both.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 d1_both.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 d1_both.o: ../include/openssl/err.h ../include/openssl/evp.h
+d1_both.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 d1_both.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 d1_both.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 d1_both.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -150,7 +152,8 @@
 d1_clnt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
 d1_clnt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 d1_clnt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-d1_clnt.o: ../include/openssl/evp.h ../include/openssl/kssl.h
+d1_clnt.o: ../include/openssl/evp.h ../include/openssl/fips.h
+d1_clnt.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
 d1_clnt.o: ../include/openssl/lhash.h ../include/openssl/md5.h
 d1_clnt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 d1_clnt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -171,20 +174,21 @@
 d1_enc.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 d1_enc.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 d1_enc.o: ../include/openssl/err.h ../include/openssl/evp.h
-d1_enc.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
-d1_enc.o: ../include/openssl/lhash.h ../include/openssl/md5.h
-d1_enc.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-d1_enc.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-d1_enc.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-d1_enc.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-d1_enc.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-d1_enc.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-d1_enc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-d1_enc.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-d1_enc.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-d1_enc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-d1_enc.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-d1_enc.o: ../include/openssl/x509_vfy.h d1_enc.c ssl_locl.h
+d1_enc.o: ../include/openssl/fips.h ../include/openssl/hmac.h
+d1_enc.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+d1_enc.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
+d1_enc.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+d1_enc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+d1_enc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+d1_enc.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
+d1_enc.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+d1_enc.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+d1_enc.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+d1_enc.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+d1_enc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+d1_enc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+d1_enc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h d1_enc.c
+d1_enc.o: ssl_locl.h
 d1_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 d1_lib.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 d1_lib.o: ../include/openssl/comp.h ../include/openssl/crypto.h
@@ -192,6 +196,7 @@
 d1_lib.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 d1_lib.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 d1_lib.o: ../include/openssl/err.h ../include/openssl/evp.h
+d1_lib.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 d1_lib.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 d1_lib.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 d1_lib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -212,6 +217,7 @@
 d1_meth.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 d1_meth.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 d1_meth.o: ../include/openssl/err.h ../include/openssl/evp.h
+d1_meth.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 d1_meth.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 d1_meth.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 d1_meth.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -232,6 +238,7 @@
 d1_pkt.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 d1_pkt.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 d1_pkt.o: ../include/openssl/err.h ../include/openssl/evp.h
+d1_pkt.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 d1_pkt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 d1_pkt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 d1_pkt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -252,7 +259,8 @@
 d1_srvr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
 d1_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 d1_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-d1_srvr.o: ../include/openssl/evp.h ../include/openssl/kssl.h
+d1_srvr.o: ../include/openssl/evp.h ../include/openssl/fips.h
+d1_srvr.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
 d1_srvr.o: ../include/openssl/lhash.h ../include/openssl/md5.h
 d1_srvr.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 d1_srvr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -272,6 +280,7 @@
 kssl.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
 kssl.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 kssl.o: ../include/openssl/ecdsa.h ../include/openssl/evp.h
+kssl.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 kssl.o: ../include/openssl/krb5_asn.h ../include/openssl/kssl.h
 kssl.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 kssl.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
@@ -291,6 +300,7 @@
 s23_clnt.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s23_clnt.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s23_clnt.o: ../include/openssl/err.h ../include/openssl/evp.h
+s23_clnt.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 s23_clnt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 s23_clnt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 s23_clnt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -311,6 +321,7 @@
 s23_lib.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s23_lib.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s23_lib.o: ../include/openssl/err.h ../include/openssl/evp.h
+s23_lib.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 s23_lib.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 s23_lib.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 s23_lib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -331,6 +342,7 @@
 s23_meth.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s23_meth.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s23_meth.o: ../include/openssl/err.h ../include/openssl/evp.h
+s23_meth.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 s23_meth.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 s23_meth.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 s23_meth.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -351,6 +363,7 @@
 s23_pkt.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s23_pkt.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s23_pkt.o: ../include/openssl/err.h ../include/openssl/evp.h
+s23_pkt.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 s23_pkt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 s23_pkt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 s23_pkt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -371,6 +384,7 @@
 s23_srvr.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s23_srvr.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s23_srvr.o: ../include/openssl/err.h ../include/openssl/evp.h
+s23_srvr.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 s23_srvr.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 s23_srvr.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 s23_srvr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -391,6 +405,7 @@
 s2_clnt.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s2_clnt.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s2_clnt.o: ../include/openssl/err.h ../include/openssl/evp.h
+s2_clnt.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 s2_clnt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 s2_clnt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 s2_clnt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -411,6 +426,7 @@
 s2_enc.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s2_enc.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s2_enc.o: ../include/openssl/err.h ../include/openssl/evp.h
+s2_enc.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 s2_enc.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 s2_enc.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 s2_enc.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -431,6 +447,7 @@
 s2_lib.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s2_lib.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s2_lib.o: ../include/openssl/err.h ../include/openssl/evp.h
+s2_lib.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 s2_lib.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 s2_lib.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
 s2_lib.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
@@ -451,6 +468,7 @@
 s2_meth.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s2_meth.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s2_meth.o: ../include/openssl/err.h ../include/openssl/evp.h
+s2_meth.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 s2_meth.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 s2_meth.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 s2_meth.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -471,6 +489,7 @@
 s2_pkt.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s2_pkt.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s2_pkt.o: ../include/openssl/err.h ../include/openssl/evp.h
+s2_pkt.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 s2_pkt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 s2_pkt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 s2_pkt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -491,6 +510,7 @@
 s2_srvr.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s2_srvr.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s2_srvr.o: ../include/openssl/err.h ../include/openssl/evp.h
+s2_srvr.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 s2_srvr.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 s2_srvr.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 s2_srvr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -511,6 +531,7 @@
 s3_both.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s3_both.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s3_both.o: ../include/openssl/err.h ../include/openssl/evp.h
+s3_both.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 s3_both.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 s3_both.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 s3_both.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -530,21 +551,23 @@
 s3_clnt.o: ../include/openssl/dh.h ../include/openssl/dsa.h
 s3_clnt.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
 s3_clnt.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
-s3_clnt.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-s3_clnt.o: ../include/openssl/evp.h ../include/openssl/kssl.h
-s3_clnt.o: ../include/openssl/lhash.h ../include/openssl/md5.h
-s3_clnt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-s3_clnt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-s3_clnt.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-s3_clnt.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s3_clnt.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s3_clnt.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-s3_clnt.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s3_clnt.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s3_clnt.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s3_clnt.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s3_clnt.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s3_clnt.o: ../include/openssl/x509_vfy.h kssl_lcl.h s3_clnt.c ssl_locl.h
+s3_clnt.o: ../include/openssl/ecdsa.h ../include/openssl/engine.h
+s3_clnt.o: ../include/openssl/err.h ../include/openssl/evp.h
+s3_clnt.o: ../include/openssl/fips.h ../include/openssl/hmac.h
+s3_clnt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s3_clnt.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
+s3_clnt.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+s3_clnt.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+s3_clnt.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+s3_clnt.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
+s3_clnt.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+s3_clnt.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s3_clnt.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s3_clnt.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s3_clnt.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s3_clnt.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s3_clnt.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h kssl_lcl.h
+s3_clnt.o: s3_clnt.c ssl_locl.h
 s3_enc.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 s3_enc.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 s3_enc.o: ../include/openssl/comp.h ../include/openssl/crypto.h
@@ -552,6 +575,7 @@
 s3_enc.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s3_enc.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s3_enc.o: ../include/openssl/err.h ../include/openssl/evp.h
+s3_enc.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 s3_enc.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 s3_enc.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
 s3_enc.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
@@ -572,7 +596,8 @@
 s3_lib.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
 s3_lib.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 s3_lib.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-s3_lib.o: ../include/openssl/evp.h ../include/openssl/kssl.h
+s3_lib.o: ../include/openssl/evp.h ../include/openssl/fips.h
+s3_lib.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
 s3_lib.o: ../include/openssl/lhash.h ../include/openssl/md5.h
 s3_lib.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 s3_lib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -593,6 +618,7 @@
 s3_meth.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s3_meth.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s3_meth.o: ../include/openssl/err.h ../include/openssl/evp.h
+s3_meth.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 s3_meth.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 s3_meth.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 s3_meth.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -613,6 +639,7 @@
 s3_pkt.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 s3_pkt.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 s3_pkt.o: ../include/openssl/err.h ../include/openssl/evp.h
+s3_pkt.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 s3_pkt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 s3_pkt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 s3_pkt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -633,21 +660,22 @@
 s3_srvr.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
 s3_srvr.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 s3_srvr.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-s3_srvr.o: ../include/openssl/evp.h ../include/openssl/hmac.h
-s3_srvr.o: ../include/openssl/krb5_asn.h ../include/openssl/kssl.h
-s3_srvr.o: ../include/openssl/lhash.h ../include/openssl/md5.h
-s3_srvr.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-s3_srvr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-s3_srvr.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-s3_srvr.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-s3_srvr.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-s3_srvr.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-s3_srvr.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-s3_srvr.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-s3_srvr.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-s3_srvr.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-s3_srvr.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-s3_srvr.o: ../include/openssl/x509_vfy.h kssl_lcl.h s3_srvr.c ssl_locl.h
+s3_srvr.o: ../include/openssl/evp.h ../include/openssl/fips.h
+s3_srvr.o: ../include/openssl/hmac.h ../include/openssl/krb5_asn.h
+s3_srvr.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+s3_srvr.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
+s3_srvr.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+s3_srvr.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+s3_srvr.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+s3_srvr.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
+s3_srvr.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+s3_srvr.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+s3_srvr.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+s3_srvr.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+s3_srvr.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+s3_srvr.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+s3_srvr.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h kssl_lcl.h
+s3_srvr.o: s3_srvr.c ssl_locl.h
 ssl_algs.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 ssl_algs.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 ssl_algs.o: ../include/openssl/comp.h ../include/openssl/crypto.h
@@ -655,6 +683,7 @@
 ssl_algs.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 ssl_algs.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 ssl_algs.o: ../include/openssl/err.h ../include/openssl/evp.h
+ssl_algs.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 ssl_algs.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 ssl_algs.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 ssl_algs.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -675,7 +704,8 @@
 ssl_asn1.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
 ssl_asn1.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 ssl_asn1.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-ssl_asn1.o: ../include/openssl/evp.h ../include/openssl/kssl.h
+ssl_asn1.o: ../include/openssl/evp.h ../include/openssl/fips.h
+ssl_asn1.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
 ssl_asn1.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 ssl_asn1.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
 ssl_asn1.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
@@ -696,7 +726,8 @@
 ssl_cert.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
 ssl_cert.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 ssl_cert.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-ssl_cert.o: ../include/openssl/evp.h ../include/openssl/kssl.h
+ssl_cert.o: ../include/openssl/evp.h ../include/openssl/fips.h
+ssl_cert.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
 ssl_cert.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 ssl_cert.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
 ssl_cert.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
@@ -717,6 +748,7 @@
 ssl_ciph.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 ssl_ciph.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 ssl_ciph.o: ../include/openssl/err.h ../include/openssl/evp.h
+ssl_ciph.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 ssl_ciph.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 ssl_ciph.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 ssl_ciph.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -736,7 +768,8 @@
 ssl_err.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
 ssl_err.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 ssl_err.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-ssl_err.o: ../include/openssl/evp.h ../include/openssl/kssl.h
+ssl_err.o: ../include/openssl/evp.h ../include/openssl/fips.h
+ssl_err.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
 ssl_err.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 ssl_err.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
 ssl_err.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
@@ -754,7 +787,8 @@
 ssl_err2.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
 ssl_err2.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 ssl_err2.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-ssl_err2.o: ../include/openssl/evp.h ../include/openssl/kssl.h
+ssl_err2.o: ../include/openssl/evp.h ../include/openssl/fips.h
+ssl_err2.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
 ssl_err2.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
 ssl_err2.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
 ssl_err2.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
@@ -773,21 +807,23 @@
 ssl_lib.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
 ssl_lib.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 ssl_lib.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-ssl_lib.o: ../include/openssl/err.h ../include/openssl/evp.h
-ssl_lib.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
-ssl_lib.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-ssl_lib.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
-ssl_lib.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-ssl_lib.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-ssl_lib.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
-ssl_lib.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
-ssl_lib.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-ssl_lib.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-ssl_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-ssl_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-ssl_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-ssl_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
-ssl_lib.o: ../include/openssl/x509v3.h kssl_lcl.h ssl_lib.c ssl_locl.h
+ssl_lib.o: ../include/openssl/engine.h ../include/openssl/err.h
+ssl_lib.o: ../include/openssl/evp.h ../include/openssl/fips.h
+ssl_lib.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+ssl_lib.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ssl_lib.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+ssl_lib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+ssl_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+ssl_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+ssl_lib.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
+ssl_lib.o: ../include/openssl/rand.h ../include/openssl/rsa.h
+ssl_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+ssl_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+ssl_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+ssl_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+ssl_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+ssl_lib.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h kssl_lcl.h
+ssl_lib.o: ssl_lib.c ssl_locl.h
 ssl_rsa.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 ssl_rsa.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 ssl_rsa.o: ../include/openssl/comp.h ../include/openssl/crypto.h
@@ -795,6 +831,7 @@
 ssl_rsa.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 ssl_rsa.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 ssl_rsa.o: ../include/openssl/err.h ../include/openssl/evp.h
+ssl_rsa.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 ssl_rsa.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 ssl_rsa.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 ssl_rsa.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -814,20 +851,22 @@
 ssl_sess.o: ../include/openssl/dsa.h ../include/openssl/dtls1.h
 ssl_sess.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 ssl_sess.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
-ssl_sess.o: ../include/openssl/err.h ../include/openssl/evp.h
-ssl_sess.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
-ssl_sess.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-ssl_sess.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-ssl_sess.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-ssl_sess.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-ssl_sess.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-ssl_sess.o: ../include/openssl/rand.h ../include/openssl/rsa.h
-ssl_sess.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-ssl_sess.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-ssl_sess.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-ssl_sess.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-ssl_sess.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-ssl_sess.o: ../include/openssl/x509_vfy.h ssl_locl.h ssl_sess.c
+ssl_sess.o: ../include/openssl/engine.h ../include/openssl/err.h
+ssl_sess.o: ../include/openssl/evp.h ../include/openssl/fips.h
+ssl_sess.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+ssl_sess.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+ssl_sess.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+ssl_sess.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+ssl_sess.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+ssl_sess.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
+ssl_sess.o: ../include/openssl/pqueue.h ../include/openssl/rand.h
+ssl_sess.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+ssl_sess.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+ssl_sess.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+ssl_sess.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+ssl_sess.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+ssl_sess.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
+ssl_sess.o: ssl_sess.c
 ssl_stat.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 ssl_stat.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 ssl_stat.o: ../include/openssl/comp.h ../include/openssl/crypto.h
@@ -835,6 +874,7 @@
 ssl_stat.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 ssl_stat.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 ssl_stat.o: ../include/openssl/err.h ../include/openssl/evp.h
+ssl_stat.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 ssl_stat.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 ssl_stat.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 ssl_stat.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -855,6 +895,7 @@
 ssl_txt.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 ssl_txt.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 ssl_txt.o: ../include/openssl/err.h ../include/openssl/evp.h
+ssl_txt.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 ssl_txt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 ssl_txt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 ssl_txt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -875,6 +916,7 @@
 t1_clnt.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 t1_clnt.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 t1_clnt.o: ../include/openssl/err.h ../include/openssl/evp.h
+t1_clnt.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 t1_clnt.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 t1_clnt.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 t1_clnt.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -895,20 +937,20 @@
 t1_enc.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 t1_enc.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 t1_enc.o: ../include/openssl/err.h ../include/openssl/evp.h
-t1_enc.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
-t1_enc.o: ../include/openssl/lhash.h ../include/openssl/md5.h
-t1_enc.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-t1_enc.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-t1_enc.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
-t1_enc.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
-t1_enc.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
-t1_enc.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-t1_enc.o: ../include/openssl/sha.h ../include/openssl/ssl.h
-t1_enc.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
-t1_enc.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
-t1_enc.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
-t1_enc.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h ssl_locl.h
-t1_enc.o: t1_enc.c
+t1_enc.o: ../include/openssl/fips.h ../include/openssl/hmac.h
+t1_enc.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
+t1_enc.o: ../include/openssl/md5.h ../include/openssl/obj_mac.h
+t1_enc.o: ../include/openssl/objects.h ../include/openssl/opensslconf.h
+t1_enc.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
+t1_enc.o: ../include/openssl/pem.h ../include/openssl/pem2.h
+t1_enc.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
+t1_enc.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
+t1_enc.o: ../include/openssl/safestack.h ../include/openssl/sha.h
+t1_enc.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
+t1_enc.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
+t1_enc.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
+t1_enc.o: ../include/openssl/tls1.h ../include/openssl/x509.h
+t1_enc.o: ../include/openssl/x509_vfy.h ssl_locl.h t1_enc.c
 t1_lib.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 t1_lib.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 t1_lib.o: ../include/openssl/comp.h ../include/openssl/conf.h
@@ -916,21 +958,21 @@
 t1_lib.o: ../include/openssl/dtls1.h ../include/openssl/e_os2.h
 t1_lib.o: ../include/openssl/ec.h ../include/openssl/ecdh.h
 t1_lib.o: ../include/openssl/ecdsa.h ../include/openssl/err.h
-t1_lib.o: ../include/openssl/evp.h ../include/openssl/hmac.h
-t1_lib.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
-t1_lib.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-t1_lib.o: ../include/openssl/ocsp.h ../include/openssl/opensslconf.h
-t1_lib.o: ../include/openssl/opensslv.h ../include/openssl/ossl_typ.h
-t1_lib.o: ../include/openssl/pem.h ../include/openssl/pem2.h
-t1_lib.o: ../include/openssl/pkcs7.h ../include/openssl/pq_compat.h
-t1_lib.o: ../include/openssl/pqueue.h ../include/openssl/rsa.h
-t1_lib.o: ../include/openssl/safestack.h ../include/openssl/sha.h
-t1_lib.o: ../include/openssl/ssl.h ../include/openssl/ssl2.h
-t1_lib.o: ../include/openssl/ssl23.h ../include/openssl/ssl3.h
-t1_lib.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-t1_lib.o: ../include/openssl/tls1.h ../include/openssl/x509.h
-t1_lib.o: ../include/openssl/x509_vfy.h ../include/openssl/x509v3.h ssl_locl.h
-t1_lib.o: t1_lib.c
+t1_lib.o: ../include/openssl/evp.h ../include/openssl/fips.h
+t1_lib.o: ../include/openssl/hmac.h ../include/openssl/kssl.h
+t1_lib.o: ../include/openssl/lhash.h ../include/openssl/obj_mac.h
+t1_lib.o: ../include/openssl/objects.h ../include/openssl/ocsp.h
+t1_lib.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
+t1_lib.o: ../include/openssl/ossl_typ.h ../include/openssl/pem.h
+t1_lib.o: ../include/openssl/pem2.h ../include/openssl/pkcs7.h
+t1_lib.o: ../include/openssl/pq_compat.h ../include/openssl/pqueue.h
+t1_lib.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
+t1_lib.o: ../include/openssl/sha.h ../include/openssl/ssl.h
+t1_lib.o: ../include/openssl/ssl2.h ../include/openssl/ssl23.h
+t1_lib.o: ../include/openssl/ssl3.h ../include/openssl/stack.h
+t1_lib.o: ../include/openssl/symhacks.h ../include/openssl/tls1.h
+t1_lib.o: ../include/openssl/x509.h ../include/openssl/x509_vfy.h
+t1_lib.o: ../include/openssl/x509v3.h ssl_locl.h t1_lib.c
 t1_meth.o: ../e_os.h ../include/openssl/asn1.h ../include/openssl/bio.h
 t1_meth.o: ../include/openssl/bn.h ../include/openssl/buffer.h
 t1_meth.o: ../include/openssl/comp.h ../include/openssl/crypto.h
@@ -938,6 +980,7 @@
 t1_meth.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 t1_meth.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 t1_meth.o: ../include/openssl/err.h ../include/openssl/evp.h
+t1_meth.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 t1_meth.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 t1_meth.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 t1_meth.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
@@ -958,6 +1001,7 @@
 t1_srvr.o: ../include/openssl/e_os2.h ../include/openssl/ec.h
 t1_srvr.o: ../include/openssl/ecdh.h ../include/openssl/ecdsa.h
 t1_srvr.o: ../include/openssl/err.h ../include/openssl/evp.h
+t1_srvr.o: ../include/openssl/fips.h ../include/openssl/hmac.h
 t1_srvr.o: ../include/openssl/kssl.h ../include/openssl/lhash.h
 t1_srvr.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
 t1_srvr.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c
index 5e59dc8..49c6760 100644
--- a/ssl/d1_clnt.c
+++ b/ssl/d1_clnt.c
@@ -1095,8 +1095,7 @@
 		 * ssl->rwstate=SSL_X509_LOOKUP; return(-1);
 		 * We then get retied later */
 		i=0;
-		if (s->ctx->client_cert_cb != NULL)
-			i=s->ctx->client_cert_cb(s,&(x509),&(pkey));
+		i = ssl_do_client_cert_cb(s, &x509, &pkey);
 		if (i < 0)
 			{
 			s->rwstate=SSL_X509_LOOKUP;
diff --git a/ssl/d1_enc.c b/ssl/d1_enc.c
index cbff749..cf3332e 100644
--- a/ssl/d1_enc.c
+++ b/ssl/d1_enc.c
@@ -115,12 +115,16 @@
 
 #include <stdio.h>
 #include "ssl_locl.h"
+#ifndef OPENSSL_NO_COMP
 #include <openssl/comp.h>
+#endif
 #include <openssl/evp.h>
 #include <openssl/hmac.h>
 #include <openssl/md5.h>
 #include <openssl/rand.h>
-
+#ifdef KSSL_DEBUG
+#include <openssl/des.h>
+#endif
 
 int dtls1_enc(SSL *s, int send)
 	{
@@ -202,10 +206,11 @@
 		{
                 unsigned long ui;
 		printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
-                        ds,rec->data,rec->input,l);
-		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
+                        (void *)ds,rec->data,rec->input,l);
+		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%ld %ld], %d iv_len\n",
                         ds->buf_len, ds->cipher->key_len,
-                        DES_KEY_SZ, DES_SCHEDULE_SZ,
+                        (unsigned long)DES_KEY_SZ,
+			(unsigned long)DES_SCHEDULE_SZ,
                         ds->cipher->iv_len);
 		printf("\t\tIV: ");
 		for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
@@ -230,10 +235,10 @@
 
 #ifdef KSSL_DEBUG
 		{
-                unsigned long i;
+                unsigned long ki;
                 printf("\trec->data=");
-		for (i=0; i<l; i++)
-                        printf(" %02x", rec->data[i]);  printf("\n");
+		for (ki=0; ki<l; ki++)
+                        printf(" %02x", rec->data[ki]);  printf("\n");
                 }
 #endif	/* KSSL_DEBUG */
 
diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c
index fc088b4..3568e97 100644
--- a/ssl/d1_lib.c
+++ b/ssl/d1_lib.c
@@ -106,6 +106,7 @@
 	pq_64bit_init(&(d1->bitmap.map));
 	pq_64bit_init(&(d1->bitmap.max_seq_num));
 	
+	d1->next_bitmap.length = d1->bitmap.length;
 	pq_64bit_init(&(d1->next_bitmap.map));
 	pq_64bit_init(&(d1->next_bitmap.max_seq_num));
 
diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c
index 377696d..eb56cf9 100644
--- a/ssl/d1_pkt.c
+++ b/ssl/d1_pkt.c
@@ -597,6 +597,7 @@
 	/* check whether this is a repeat, or aged record */
 	if ( ! dtls1_record_replay_check(s, bitmap, &(rr->seq_num)))
 		{
+		rr->length = 0;
 		s->packet_length=0; /* dump this record */
 		goto again;     /* get another record */
 		}
@@ -811,6 +812,14 @@
              *  may be fragmented--don't always expect dest_maxlen bytes */
 			if ( rr->length < dest_maxlen)
 				{
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+				/*
+				 * for normal alerts rr->length is 2, while
+				 * dest_maxlen is 7 if we were to handle this
+				 * non-existing alert...
+				 */
+				FIX ME
+#endif
 				s->rstate=SSL_ST_READ_HEADER;
 				rr->length = 0;
 				goto start;
@@ -1251,7 +1260,7 @@
 	else 
 		s->s3->wnum += i;
 
-	return tot + i;
+	return i;
 	}
 
 int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, int create_empty_fragment)
@@ -1576,7 +1585,7 @@
 	{
 	int i,j;
 	void (*cb)(const SSL *ssl,int type,int val)=NULL;
-	unsigned char buf[2 + 2 + 3]; /* alert level + alert desc + message seq +frag_off */
+	unsigned char buf[DTLS1_AL_HEADER_LENGTH];
 	unsigned char *ptr = &buf[0];
 
 	s->s3->alert_dispatch=0;
@@ -1585,6 +1594,7 @@
 	*ptr++ = s->s3->send_alert[0];
 	*ptr++ = s->s3->send_alert[1];
 
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
 	if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE)
 		{	
 		s2n(s->d1->handshake_read_seq, ptr);
@@ -1600,6 +1610,7 @@
 #endif
 		l2n3(s->d1->r_msg_hdr.frag_off, ptr);
 		}
+#endif
 
 	i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0);
 	if (i <= 0)
@@ -1609,8 +1620,11 @@
 		}
 	else
 		{
-		if ( s->s3->send_alert[0] == SSL3_AL_FATAL ||
-			s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE)
+		if (s->s3->send_alert[0] == SSL3_AL_FATAL
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+		    || s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+#endif
+		   )
 			(void)BIO_flush(s->wbio);
 
 		if (s->msg_callback)
diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c
index 927b01f..0bbf8ae 100644
--- a/ssl/d1_srvr.c
+++ b/ssl/d1_srvr.c
@@ -732,7 +732,7 @@
 
 		d = dtls1_set_message_header(s, d, SSL3_MT_SERVER_HELLO, l, 0, l);
 
-		s->state=SSL3_ST_CW_CLNT_HELLO_B;
+		s->state=SSL3_ST_SW_SRVR_HELLO_B;
 		/* number of bytes to write */
 		s->init_num=p-buf;
 		s->init_off=0;
@@ -741,7 +741,7 @@
 		dtls1_buffer_message(s, 0);
 		}
 
-	/* SSL3_ST_CW_CLNT_HELLO_B */
+	/* SSL3_ST_SW_SRVR_HELLO_B */
 	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
 	}
 
@@ -765,7 +765,7 @@
 		dtls1_buffer_message(s, 0);
 		}
 
-	/* SSL3_ST_CW_CLNT_HELLO_B */
+	/* SSL3_ST_SW_SRVR_DONE_B */
 	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
 	}
 
diff --git a/ssl/dtls1.h b/ssl/dtls1.h
index a663cf8..f159d37 100644
--- a/ssl/dtls1.h
+++ b/ssl/dtls1.h
@@ -70,7 +70,10 @@
 #define DTLS1_VERSION			0xFEFF
 #define DTLS1_BAD_VER			0x0100
 
+#if 0
+/* this alert description is not specified anywhere... */
 #define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE    110
+#endif
 
 /* lengths of messages */
 #define DTLS1_COOKIE_LENGTH                     32
@@ -84,7 +87,11 @@
 
 #define DTLS1_CCS_HEADER_LENGTH                  1
 
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
 #define DTLS1_AL_HEADER_LENGTH                   7
+#else
+#define DTLS1_AL_HEADER_LENGTH                   2
+#endif
 
 
 typedef struct dtls1_bitmap_st
diff --git a/ssl/kssl.c b/ssl/kssl.c
index 6da75e6..019030a 100644
--- a/ssl/kssl.c
+++ b/ssl/kssl.c
@@ -946,7 +946,7 @@
 	if (kssl_err == NULL)  return;
 
 	kssl_err->reason = reason;
-	BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, text);
+	BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, "%s", text);
 	return;
         }
 
diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c
index c45a8e0..bc91817 100644
--- a/ssl/s23_clnt.c
+++ b/ssl/s23_clnt.c
@@ -257,6 +257,14 @@
 			version_major = TLS1_VERSION_MAJOR;
 			version_minor = TLS1_VERSION_MINOR;
 			}
+#ifdef OPENSSL_FIPS
+		else if(FIPS_mode())
+			{
+			SSLerr(SSL_F_SSL23_CLIENT_HELLO,
+					SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
+			return -1;
+			}
+#endif
 		else if (version == SSL3_VERSION)
 			{
 			version_major = SSL3_VERSION_MAJOR;
@@ -536,6 +544,14 @@
 		if ((p[2] == SSL3_VERSION_MINOR) &&
 			!(s->options & SSL_OP_NO_SSLv3))
 			{
+#ifdef OPENSSL_FIPS
+			if(FIPS_mode())
+				{
+				SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,
+					SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
+				goto err;
+				}
+#endif
 			s->version=SSL3_VERSION;
 			s->method=SSLv3_client_method();
 			}
diff --git a/ssl/s23_srvr.c b/ssl/s23_srvr.c
index 6637bb9..ba06e7a 100644
--- a/ssl/s23_srvr.c
+++ b/ssl/s23_srvr.c
@@ -386,6 +386,15 @@
 			}
 		}
 
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode() && (s->version < TLS1_VERSION))
+		{
+		SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,
+					SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
+		goto err;
+		}
+#endif
+
 	if (s->state == SSL23_ST_SR_CLNT_HELLO_B)
 		{
 		/* we have SSLv3/TLSv1 in an SSLv2 header
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 81ae11b..5030848 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -130,10 +130,17 @@
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 #include <openssl/md5.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
+
 #ifndef OPENSSL_NO_DH
 #include <openssl/dh.h>
 #endif
 #include <openssl/bn.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
 
 static SSL_METHOD *ssl3_get_client_method(int ver);
 static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b);
@@ -166,7 +173,7 @@
 	long num1;
 	void (*cb)(const SSL *ssl,int type,int val)=NULL;
 	int ret= -1;
-	int new_state,state,skip=0;;
+	int new_state,state,skip=0;
 
 	RAND_add(&Time,sizeof(Time),0);
 	ERR_clear_error();
@@ -999,7 +1006,7 @@
 	                 == (SSL_aKRB5|SSL_kKRB5))? 0: 1;
 
 #ifdef KSSL_DEBUG
-	printf("pkey,x = %p, %p\n", pkey,x);
+	printf("pkey,x = %p, %p\n", (void *)pkey,(void *)x);
 	printf("ssl_cert_type(x,pkey) = %d\n", ssl_cert_type(x,pkey));
 	printf("cipher, alg, nc = %s, %lx, %d\n", s->s3->tmp.new_cipher->name,
 	        s->s3->tmp.new_cipher->algorithms, need_cert);
@@ -1415,6 +1422,8 @@
 			q=md_buf;
 			for (num=2; num > 0; num--)
 				{
+				EVP_MD_CTX_set_flags(&md_ctx,
+					EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
 				EVP_DigestInit_ex(&md_ctx,(num == 2)
 					?s->ctx->md5:s->ctx->sha1, NULL);
 				EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
@@ -1768,7 +1777,7 @@
 		goto f_err;
 		}
 	n2l3(p, resplen);
-	if (resplen + 4 != n)
+	if (resplen + 4 != (unsigned long)n)
 		{
 		al = SSL_AD_DECODE_ERROR;
 		SSLerr(SSL_F_SSL3_GET_CERT_STATUS,SSL_R_LENGTH_MISMATCH);
@@ -2061,12 +2070,12 @@
 			{
 			DH *dh_srvr,*dh_clnt;
 
-                        if (s->session->sess_cert == NULL) 
-                                {
-                                ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
-                                SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
-                                goto err;
-                                }
+			if (s->session->sess_cert == NULL) 
+				{
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
+				goto err;
+			        }
 
 			if (s->session->sess_cert->peer_dh_tmp != NULL)
 				dh_srvr=s->session->sess_cert->peer_dh_tmp;
@@ -2448,8 +2457,7 @@
 		 * ssl->rwstate=SSL_X509_LOOKUP; return(-1);
 		 * We then get retied later */
 		i=0;
-		if (s->ctx->client_cert_cb != NULL)
-			i=s->ctx->client_cert_cb(s,&(x509),&(pkey));
+		i = ssl_do_client_cert_cb(s, &x509, &pkey);
 		if (i < 0)
 			{
 			s->rwstate=SSL_X509_LOOKUP;
@@ -2716,3 +2724,21 @@
 	return 1;
 	}
 #endif
+
+int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
+	{
+	int i = 0;
+#ifndef OPENSSL_NO_ENGINE
+	if (s->ctx->client_cert_engine)
+		{
+		i = ENGINE_load_ssl_client_cert(s->ctx->client_cert_engine, s,
+						SSL_get_client_CA_list(s),
+						px509, ppkey, NULL, NULL, NULL);
+		if (i != 0)
+			return i;
+		}
+#endif
+	if (s->ctx->client_cert_cb)
+		i = s->ctx->client_cert_cb(s,px509,ppkey);
+	return i;
+	}
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
index 2859351..06e5466 100644
--- a/ssl/s3_enc.c
+++ b/ssl/s3_enc.c
@@ -146,6 +146,7 @@
 #endif
 	k=0;
 	EVP_MD_CTX_init(&m5);
+	EVP_MD_CTX_set_flags(&m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
 	EVP_MD_CTX_init(&s1);
 	for (i=0; (int)i<num; i+=MD5_DIGEST_LENGTH)
 		{
@@ -518,6 +519,8 @@
 
 void ssl3_init_finished_mac(SSL *s)
 	{
+	EVP_MD_CTX_set_flags(&(s->s3->finish_dgst1),
+		EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
 	EVP_DigestInit_ex(&(s->s3->finish_dgst1),s->ctx->md5, NULL);
 	EVP_DigestInit_ex(&(s->s3->finish_dgst2),s->ctx->sha1, NULL);
 	}
@@ -554,6 +557,7 @@
 	EVP_MD_CTX ctx;
 
 	EVP_MD_CTX_init(&ctx);
+	EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
 	EVP_MD_CTX_copy_ex(&ctx,in_ctx);
 
 	n=EVP_MD_CTX_size(&ctx);
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index bdbcd44..8916a0b 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -158,7 +158,7 @@
 	SSL3_TXT_RSA_NULL_SHA,
 	SSL3_CK_RSA_NULL_SHA,
 	SSL_kRSA|SSL_aRSA|SSL_eNULL |SSL_SHA1|SSL_SSLV3,
-	SSL_NOT_EXP|SSL_STRONG_NONE,
+	SSL_NOT_EXP|SSL_STRONG_NONE|SSL_FIPS,
 	0,
 	0,
 	0,
@@ -264,7 +264,7 @@
 	SSL3_TXT_RSA_DES_192_CBC3_SHA,
 	SSL3_CK_RSA_DES_192_CBC3_SHA,
 	SSL_kRSA|SSL_aRSA|SSL_3DES |SSL_SHA1|SSL_SSLV3,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	0,
 	168,
 	168,
@@ -304,7 +304,7 @@
 	SSL3_TXT_DH_DSS_DES_192_CBC3_SHA,
 	SSL3_CK_DH_DSS_DES_192_CBC3_SHA,
 	SSL_kDHd |SSL_aDH|SSL_3DES |SSL_SHA1|SSL_SSLV3,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	0,
 	168,
 	168,
@@ -343,7 +343,7 @@
 	SSL3_TXT_DH_RSA_DES_192_CBC3_SHA,
 	SSL3_CK_DH_RSA_DES_192_CBC3_SHA,
 	SSL_kDHr |SSL_aDH|SSL_3DES |SSL_SHA1|SSL_SSLV3,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	0,
 	168,
 	168,
@@ -384,7 +384,7 @@
 	SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA,
 	SSL3_CK_EDH_DSS_DES_192_CBC3_SHA,
 	SSL_kEDH|SSL_aDSS|SSL_3DES |SSL_SHA1|SSL_SSLV3,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	0,
 	168,
 	168,
@@ -423,7 +423,7 @@
 	SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA,
 	SSL3_CK_EDH_RSA_DES_192_CBC3_SHA,
 	SSL_kEDH|SSL_aRSA|SSL_3DES |SSL_SHA1|SSL_SSLV3,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	0,
 	168,
 	168,
@@ -488,7 +488,7 @@
 	SSL3_TXT_ADH_DES_192_CBC_SHA,
 	SSL3_CK_ADH_DES_192_CBC_SHA,
 	SSL_kEDH |SSL_aNULL|SSL_3DES |SSL_SHA1|SSL_SSLV3,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	0,
 	168,
 	168,
@@ -563,7 +563,7 @@
 	SSL3_TXT_KRB5_DES_192_CBC3_SHA,
 	SSL3_CK_KRB5_DES_192_CBC3_SHA,
 	SSL_kKRB5|SSL_aKRB5|  SSL_3DES|SSL_SHA1  |SSL_SSLV3,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	0,
 	168,
 	168,
@@ -747,7 +747,7 @@
 	TLS1_TXT_RSA_WITH_AES_128_SHA,
 	TLS1_CK_RSA_WITH_AES_128_SHA,
 	SSL_kRSA|SSL_aRSA|SSL_AES|SSL_SHA |SSL_TLSV1,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	0,
 	128,
 	128,
@@ -760,7 +760,7 @@
 	TLS1_TXT_DH_DSS_WITH_AES_128_SHA,
 	TLS1_CK_DH_DSS_WITH_AES_128_SHA,
 	SSL_kDHd|SSL_aDH|SSL_AES|SSL_SHA|SSL_TLSV1,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	0,
 	128,
 	128,
@@ -773,7 +773,7 @@
 	TLS1_TXT_DH_RSA_WITH_AES_128_SHA,
 	TLS1_CK_DH_RSA_WITH_AES_128_SHA,
 	SSL_kDHr|SSL_aDH|SSL_AES|SSL_SHA|SSL_TLSV1,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	0,
 	128,
 	128,
@@ -786,7 +786,7 @@
 	TLS1_TXT_DHE_DSS_WITH_AES_128_SHA,
 	TLS1_CK_DHE_DSS_WITH_AES_128_SHA,
 	SSL_kEDH|SSL_aDSS|SSL_AES|SSL_SHA|SSL_TLSV1,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	0,
 	128,
 	128,
@@ -799,7 +799,7 @@
 	TLS1_TXT_DHE_RSA_WITH_AES_128_SHA,
 	TLS1_CK_DHE_RSA_WITH_AES_128_SHA,
 	SSL_kEDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	0,
 	128,
 	128,
@@ -812,7 +812,7 @@
 	TLS1_TXT_ADH_WITH_AES_128_SHA,
 	TLS1_CK_ADH_WITH_AES_128_SHA,
 	SSL_kEDH|SSL_aNULL|SSL_AES|SSL_SHA|SSL_TLSV1,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	0,
 	128,
 	128,
@@ -826,7 +826,7 @@
 	TLS1_TXT_RSA_WITH_AES_256_SHA,
 	TLS1_CK_RSA_WITH_AES_256_SHA,
 	SSL_kRSA|SSL_aRSA|SSL_AES|SSL_SHA |SSL_TLSV1,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	0,
 	256,
 	256,
@@ -839,7 +839,7 @@
 	TLS1_TXT_DH_DSS_WITH_AES_256_SHA,
 	TLS1_CK_DH_DSS_WITH_AES_256_SHA,
 	SSL_kDHd|SSL_aDH|SSL_AES|SSL_SHA|SSL_TLSV1,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	0,
 	256,
 	256,
@@ -852,7 +852,7 @@
 	TLS1_TXT_DH_RSA_WITH_AES_256_SHA,
 	TLS1_CK_DH_RSA_WITH_AES_256_SHA,
 	SSL_kDHr|SSL_aDH|SSL_AES|SSL_SHA|SSL_TLSV1,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	0,
 	256,
 	256,
@@ -865,7 +865,7 @@
 	TLS1_TXT_DHE_DSS_WITH_AES_256_SHA,
 	TLS1_CK_DHE_DSS_WITH_AES_256_SHA,
 	SSL_kEDH|SSL_aDSS|SSL_AES|SSL_SHA|SSL_TLSV1,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	0,
 	256,
 	256,
@@ -878,7 +878,7 @@
 	TLS1_TXT_DHE_RSA_WITH_AES_256_SHA,
 	TLS1_CK_DHE_RSA_WITH_AES_256_SHA,
 	SSL_kEDH|SSL_aRSA|SSL_AES|SSL_SHA|SSL_TLSV1,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	0,
 	256,
 	256,
@@ -891,7 +891,7 @@
 	TLS1_TXT_ADH_WITH_AES_256_SHA,
 	TLS1_CK_ADH_WITH_AES_256_SHA,
 	SSL_kEDH|SSL_aNULL|SSL_AES|SSL_SHA|SSL_TLSV1,
-	SSL_NOT_EXP|SSL_HIGH,
+	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
 	0,
 	256,
 	256,
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index 44c7c14..9476dcd 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -753,8 +753,15 @@
 			s->rwstate=SSL_NOTHING;
 			return(s->s3->wpend_ret);
 			}
-		else if (i <= 0)
+		else if (i <= 0) {
+			if (s->version == DTLS1_VERSION ||
+			    s->version == DTLS1_BAD_VER) {
+				/* For DTLS, just drop it. That's kind of the whole
+				   point in using a datagram service */
+				s->s3->wbuf.left = 0;
+			}
 			return(i);
+		}
 		s->s3->wbuf.offset+=i;
 		s->s3->wbuf.left-=i;
 		}
@@ -1225,6 +1232,13 @@
 
 	if (s->s3->tmp.key_block == NULL)
 		{
+		if (s->session == NULL) 
+			{
+			/* might happen if dtls1_read_bytes() calls this */
+			SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY);
+			return (0);
+			}
+
 		s->session->cipher=s->s3->tmp.new_cipher;
 		if (!s->method->ssl3_enc->setup_key_block(s)) return(0);
 		}
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index c0c62b3..80b45eb 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -902,21 +902,27 @@
 				break;
 				}
 			}
+		if (j == 0 && (s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_SSL_CIPHER_num(ciphers) == 1))
+			{
+			/* Special case as client bug workaround: the previously used cipher may
+			 * not be in the current list, the client instead might be trying to
+			 * continue using a cipher that before wasn't chosen due to server
+			 * preferences.  We'll have to reject the connection if the cipher is not
+			 * enabled, though. */
+			c = sk_SSL_CIPHER_value(ciphers, 0);
+			if (sk_SSL_CIPHER_find(SSL_get_ciphers(s), c) >= 0)
+				{
+				s->session->cipher = c;
+				j = 1;
+				}
+			}
 		if (j == 0)
 			{
-			if ((s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_SSL_CIPHER_num(ciphers) == 1))
-				{
-				/* Very bad for multi-threading.... */
-				s->session->cipher=sk_SSL_CIPHER_value(ciphers, 0);
-				}
-			else
-				{
-				/* we need to have the cipher in the cipher
-				 * list if we are asked to reuse it */
-				al=SSL_AD_ILLEGAL_PARAMETER;
-				SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_REQUIRED_CIPHER_MISSING);
-				goto f_err;
-				}
+			/* we need to have the cipher in the cipher
+			 * list if we are asked to reuse it */
+			al=SSL_AD_ILLEGAL_PARAMETER;
+			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_REQUIRED_CIPHER_MISSING);
+			goto f_err;
 			}
 		}
 
@@ -1172,13 +1178,13 @@
 		*(d++)=SSL3_MT_SERVER_HELLO;
 		l2n3(l,d);
 
-		s->state=SSL3_ST_CW_CLNT_HELLO_B;
+		s->state=SSL3_ST_SW_SRVR_HELLO_B;
 		/* number of bytes to write */
 		s->init_num=p-buf;
 		s->init_off=0;
 		}
 
-	/* SSL3_ST_CW_CLNT_HELLO_B */
+	/* SSL3_ST_SW_SRVR_HELLO_B */
 	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
 	}
 
@@ -1202,7 +1208,7 @@
 		s->init_off=0;
 		}
 
-	/* SSL3_ST_CW_CLNT_HELLO_B */
+	/* SSL3_ST_SW_SRVR_DONE_B */
 	return(ssl3_do_write(s,SSL3_RT_HANDSHAKE));
 	}
 
@@ -1540,6 +1546,8 @@
 				j=0;
 				for (num=2; num > 0; num--)
 					{
+					EVP_MD_CTX_set_flags(&md_ctx,
+						EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
 					EVP_DigestInit_ex(&md_ctx,(num == 2)
 						?s->ctx->md5:s->ctx->sha1, NULL);
 					EVP_DigestUpdate(&md_ctx,&(s->s3->client_random[0]),SSL3_RANDOM_SIZE);
diff --git a/ssl/ssl.h b/ssl/ssl.h
index 6df921f..ff8a128 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -252,6 +252,7 @@
 #define SSL_TXT_LOW		"LOW"
 #define SSL_TXT_MEDIUM		"MEDIUM"
 #define SSL_TXT_HIGH		"HIGH"
+#define SSL_TXT_FIPS		"FIPS"
 #define SSL_TXT_kFZA		"kFZA"
 #define	SSL_TXT_aFZA		"aFZA"
 #define SSL_TXT_eFZA		"eFZA"
@@ -361,9 +362,6 @@
 
 DECLARE_STACK_OF(SSL_CIPHER)
 
-typedef struct ssl_st SSL;
-typedef struct ssl_ctx_st SSL_CTX;
-
 /* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
 typedef struct ssl_method_st
 	{
@@ -760,6 +758,12 @@
 
 	int quiet_shutdown;
 
+#ifndef OPENSSL_ENGINE
+	/* Engine to pass requests for client certs to
+	 */
+	ENGINE *client_cert_engine;
+#endif
+
 #ifndef OPENSSL_NO_TLSEXT
 	/* TLS extensions servername callback */
 	int (*tlsext_servername_callback)(SSL*, int *, void *);
@@ -829,6 +833,9 @@
 void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val);
 void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
 int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+#ifndef OPENSSL_NO_ENGINE
+int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e);
+#endif
 void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len));
 void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len));
 
@@ -1702,6 +1709,7 @@
 #define SSL_F_SSL3_CONNECT				 132
 #define SSL_F_SSL3_CTRL					 213
 #define SSL_F_SSL3_CTX_CTRL				 133
+#define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC		 279
 #define SSL_F_SSL3_ENC					 134
 #define SSL_F_SSL3_GENERATE_KEY_BLOCK			 238
 #define SSL_F_SSL3_GET_CERTIFICATE_REQUEST		 135
@@ -1755,6 +1763,7 @@
 #define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY			 168
 #define SSL_F_SSL_CTX_NEW				 169
 #define SSL_F_SSL_CTX_SET_CIPHER_LIST			 269
+#define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE		 278
 #define SSL_F_SSL_CTX_SET_PURPOSE			 226
 #define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT		 219
 #define SSL_F_SSL_CTX_SET_SSL_VERSION			 170
@@ -1935,6 +1944,7 @@
 #define SSL_R_NO_CIPHERS_SPECIFIED			 183
 #define SSL_R_NO_CIPHER_LIST				 184
 #define SSL_R_NO_CIPHER_MATCH				 185
+#define SSL_R_NO_CLIENT_CERT_METHOD			 317
 #define SSL_R_NO_CLIENT_CERT_RECEIVED			 186
 #define SSL_R_NO_COMPRESSION_SPECIFIED			 187
 #define SSL_R_NO_METHOD_SPECIFIED			 188
diff --git a/ssl/ssl_asn1.c b/ssl/ssl_asn1.c
index 6e14f4d..0f9a348 100644
--- a/ssl/ssl_asn1.c
+++ b/ssl/ssl_asn1.c
@@ -353,7 +353,7 @@
 	memcpy(ret->session_id,os.data,os.length);
 
 	M_ASN1_D2I_get_x(ASN1_OCTET_STRING,osp,d2i_ASN1_OCTET_STRING);
-	if (ret->master_key_length > SSL_MAX_MASTER_KEY_LENGTH)
+	if (os.length > SSL_MAX_MASTER_KEY_LENGTH)
 		ret->master_key_length=SSL_MAX_MASTER_KEY_LENGTH;
 	else
 		ret->master_key_length=os.length;
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index 725f7f3..52f91cf 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -115,7 +115,10 @@
  */
 #include <stdio.h>
 #include <openssl/objects.h>
+#ifndef OPENSSL_NO_COMP
 #include <openssl/comp.h>
+#endif
+
 #include "ssl_locl.h"
 
 #define SSL_ENC_DES_IDX		0
@@ -222,6 +225,7 @@
 	{0,SSL_TXT_LOW,   0, 0,   SSL_LOW, 0,0,0,0,SSL_STRONG_MASK},
 	{0,SSL_TXT_MEDIUM,0, 0,SSL_MEDIUM, 0,0,0,0,SSL_STRONG_MASK},
 	{0,SSL_TXT_HIGH,  0, 0,  SSL_HIGH, 0,0,0,0,SSL_STRONG_MASK},
+	{0,SSL_TXT_FIPS,  0, 0,  SSL_FIPS, 0,0,0,0,SSL_FIPS|SSL_STRONG_NONE},
 	};
 
 void ssl_load_ciphers(void)
@@ -515,7 +519,12 @@
 		c = ssl_method->get_cipher(i);
 #define IS_MASKED(c) ((c)->algorithms & (((c)->alg_bits == 256) ? m256 : mask))
 		/* drop those that use any of that is not available */
+#ifdef OPENSSL_FIPS
+		if ((c != NULL) && c->valid && !IS_MASKED(c)
+			&& (!FIPS_mode() || (c->algo_strength & SSL_FIPS)))
+#else
 		if ((c != NULL) && c->valid && !IS_MASKED(c))
+#endif
 			{
 			co_list[co_list_num].cipher = c;
 			co_list[co_list_num].next = NULL;
@@ -1054,7 +1063,11 @@
 	 */
 	for (curr = head; curr != NULL; curr = curr->next)
 		{
+#ifdef OPENSSL_FIPS
+		if (curr->active && (!FIPS_mode() || curr->cipher->algo_strength & SSL_FIPS))
+#else
 		if (curr->active)
+#endif
 			{
 			sk_SSL_CIPHER_push(cipherstack, curr->cipher);
 #ifdef CIPHER_DEBUG
@@ -1342,7 +1355,7 @@
 	comp->method=cm;
 	load_builtin_compressions();
 	if (ssl_comp_methods
-		&& !sk_SSL_COMP_find(ssl_comp_methods,comp))
+		&& sk_SSL_COMP_find(ssl_comp_methods,comp) >= 0)
 		{
 		OPENSSL_free(comp);
 		MemCheck_on();
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index 50779c1..24a994f 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -1,6 +1,6 @@
 /* ssl/ssl_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2007 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
@@ -138,6 +138,7 @@
 {ERR_FUNC(SSL_F_SSL3_CONNECT),	"SSL3_CONNECT"},
 {ERR_FUNC(SSL_F_SSL3_CTRL),	"SSL3_CTRL"},
 {ERR_FUNC(SSL_F_SSL3_CTX_CTRL),	"SSL3_CTX_CTRL"},
+{ERR_FUNC(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC),	"SSL3_DO_CHANGE_CIPHER_SPEC"},
 {ERR_FUNC(SSL_F_SSL3_ENC),	"SSL3_ENC"},
 {ERR_FUNC(SSL_F_SSL3_GENERATE_KEY_BLOCK),	"SSL3_GENERATE_KEY_BLOCK"},
 {ERR_FUNC(SSL_F_SSL3_GET_CERTIFICATE_REQUEST),	"SSL3_GET_CERTIFICATE_REQUEST"},
@@ -191,6 +192,7 @@
 {ERR_FUNC(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY),	"SSL_CTX_check_private_key"},
 {ERR_FUNC(SSL_F_SSL_CTX_NEW),	"SSL_CTX_new"},
 {ERR_FUNC(SSL_F_SSL_CTX_SET_CIPHER_LIST),	"SSL_CTX_set_cipher_list"},
+{ERR_FUNC(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE),	"SSL_CTX_set_client_cert_engine"},
 {ERR_FUNC(SSL_F_SSL_CTX_SET_PURPOSE),	"SSL_CTX_set_purpose"},
 {ERR_FUNC(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT),	"SSL_CTX_set_session_id_context"},
 {ERR_FUNC(SSL_F_SSL_CTX_SET_SSL_VERSION),	"SSL_CTX_set_ssl_version"},
@@ -374,6 +376,7 @@
 {ERR_REASON(SSL_R_NO_CIPHERS_SPECIFIED)  ,"no ciphers specified"},
 {ERR_REASON(SSL_R_NO_CIPHER_LIST)        ,"no cipher list"},
 {ERR_REASON(SSL_R_NO_CIPHER_MATCH)       ,"no cipher match"},
+{ERR_REASON(SSL_R_NO_CLIENT_CERT_METHOD) ,"no client cert method"},
 {ERR_REASON(SSL_R_NO_CLIENT_CERT_RECEIVED),"no client cert received"},
 {ERR_REASON(SSL_R_NO_COMPRESSION_SPECIFIED),"no compression specified"},
 {ERR_REASON(SSL_R_NO_METHOD_SPECIFIED)   ,"no method specified"},
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 065411a..893abff 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -130,6 +130,9 @@
 #ifndef OPENSSL_NO_DH
 #include <openssl/dh.h>
 #endif
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
 
 const char *SSL_version_str=OPENSSL_VERSION_TEXT;
 
@@ -507,6 +510,8 @@
 
 	if (s->ctx) SSL_CTX_free(s->ctx);
 #ifndef OPENSSL_NO_TLSEXT
+	if (s->tlsext_hostname)
+		OPENSSL_free(s->tlsext_hostname);
 	if (s->initial_ctx) SSL_CTX_free(s->initial_ctx);
 	if (s->tlsext_ocsp_exts)
 		sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
@@ -1393,6 +1398,14 @@
 		return(NULL);
 		}
 
+#ifdef OPENSSL_FIPS
+	if (FIPS_mode() && (meth->version < TLS1_VERSION))	
+		{
+		SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
+		return NULL;
+		}
+#endif
+
 	if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0)
 		{
 		SSLerr(SSL_F_SSL_CTX_NEW,SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
@@ -1513,6 +1526,27 @@
 
 #endif
 
+#ifndef OPENSSL_NO_ENGINE
+	ret->client_cert_engine = NULL;
+#ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO
+#define eng_strx(x)	#x
+#define eng_str(x)	eng_strx(x)
+	/* Use specific client engine automatically... ignore errors */
+	{
+	ENGINE *eng;
+	eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO));
+	if (!eng)
+		{
+		ERR_clear_error();
+		ENGINE_load_builtin_engines();
+		eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO));
+		}
+	if (!eng || !SSL_CTX_set_client_cert_engine(ret, eng))
+		ERR_clear_error();
+	}
+#endif
+#endif
+
 	return(ret);
 err:
 	SSLerr(SSL_F_SSL_CTX_NEW,ERR_R_MALLOC_FAILURE);
@@ -1583,6 +1617,10 @@
 #else
 	a->comp_methods = NULL;
 #endif
+#ifndef OPENSSL_NO_ENGINE
+	if (a->client_cert_engine)
+		ENGINE_finish(a->client_cert_engine);
+#endif
 	OPENSSL_free(a);
 	}
 
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index de94c0d..ed4ddbb 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -124,7 +124,9 @@
 #include "e_os.h"
 
 #include <openssl/buffer.h>
+#ifndef OPENSSL_NO_COMP
 #include <openssl/comp.h>
+#endif
 #include <openssl/bio.h>
 #include <openssl/stack.h>
 #ifndef OPENSSL_NO_RSA
@@ -330,8 +332,9 @@
 #define SSL_LOW			0x00000020L
 #define SSL_MEDIUM		0x00000040L
 #define SSL_HIGH		0x00000080L
+#define SSL_FIPS		0x00000100L
 
-/* we have used 000000ff - 24 bits left to go */
+/* we have used 000001ff - 23 bits left to go */
 
 /*
  * Macros to check the export status and cipher strength for export ciphers.
@@ -499,6 +502,7 @@
 	int (*alert_value)(int);
 	} SSL3_ENC_METHOD;
 
+#ifndef OPENSSL_NO_COMP
 /* Used for holding the relevant compression methods loaded into SSL_CTX */
 typedef struct ssl3_comp_st
 	{
@@ -506,6 +510,7 @@
 	char *name;	/* Text name used for the compression type */
 	COMP_METHOD *method; /* The method :-) */
 	} SSL3_COMP;
+#endif
 
 extern SSL3_ENC_METHOD ssl3_undef_enc_method;
 OPENSSL_EXTERN SSL_CIPHER ssl2_ciphers[];
@@ -874,6 +879,7 @@
 int ssl3_get_cert_status(SSL *s);
 int ssl3_get_server_done(SSL *s);
 int ssl3_send_client_verify(SSL *s);
+int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey);
 int ssl3_send_client_certificate(SSL *s);
 int ssl3_send_client_key_exchange(SSL *s);
 int ssl3_get_key_exchange(SSL *s);
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
index ee88be2..8391d62 100644
--- a/ssl/ssl_sess.c
+++ b/ssl/ssl_sess.c
@@ -59,6 +59,9 @@
 #include <stdio.h>
 #include <openssl/lhash.h>
 #include <openssl/rand.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
 #include "ssl_locl.h"
 
 static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
@@ -870,6 +873,25 @@
 	return ctx->client_cert_cb;
 	}
 
+#ifndef OPENSSL_NO_ENGINE
+int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e)
+	{
+	if (!ENGINE_init(e))
+		{
+		SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, ERR_R_ENGINE_LIB);
+		return 0;
+		}
+	if(!ENGINE_get_ssl_client_cert_function(e))
+		{
+		SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, SSL_R_NO_CLIENT_CERT_METHOD);
+		ENGINE_finish(e);
+		return 0;
+		}
+	ctx->client_cert_engine = e;
+	return 1;
+	}
+#endif
+
 void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx,
 	int (*cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len))
 	{
diff --git a/ssl/ssltest.c b/ssl/ssltest.c
index 41dafbb..b09c542 100644
--- a/ssl/ssltest.c
+++ b/ssl/ssltest.c
@@ -229,6 +229,9 @@
 	{
 	fprintf(stderr,"usage: ssltest [args ...]\n");
 	fprintf(stderr,"\n");
+#ifdef OPENSSL_FIPS
+	fprintf(stderr,"-F             - run test in FIPS mode\n");
+#endif
 	fprintf(stderr," -server_auth  - check server certificate\n");
 	fprintf(stderr," -client_auth  - do client authentication\n");
 	fprintf(stderr," -proxy        - allow proxy certificates\n");
@@ -410,7 +413,7 @@
 	long bytes=256L;
 #ifndef OPENSSL_NO_DH
 	DH *dh;
-	int dhe1024 = 0, dhe1024dsa = 0;
+	int dhe1024 = 1, dhe1024dsa = 0;
 #endif
 #ifndef OPENSSL_NO_ECDH
 	EC_KEY *ecdh = NULL;
@@ -425,6 +428,9 @@
 #endif
 	STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
 	int test_cipherlist = 0;
+#ifdef OPENSSL_FIPS
+	int fips_mode=0;
+#endif
 
 	verbose = 0;
 	debug = 0;
@@ -456,7 +462,16 @@
 
 	while (argc >= 1)
 		{
-		if	(strcmp(*argv,"-server_auth") == 0)
+		if(!strcmp(*argv,"-F"))
+			{
+#ifdef OPENSSL_FIPS
+			fips_mode=1;
+#else
+			fprintf(stderr,"not compiled with FIPS support, so exitting without running.\n");
+			EXIT(0);
+#endif
+			}
+		else if	(strcmp(*argv,"-server_auth") == 0)
 			server_auth=1;
 		else if	(strcmp(*argv,"-client_auth") == 0)
 			client_auth=1;
@@ -638,6 +653,20 @@
 		EXIT(1);
 		}
 
+#ifdef OPENSSL_FIPS
+	if(fips_mode)
+		{
+		if(!FIPS_mode_set(1))
+			{
+			ERR_load_crypto_strings();
+			ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE));
+			EXIT(1);
+			}
+		else
+			fprintf(stderr,"*** IN FIPS MODE ***\n");
+		}
+#endif
+
 	if (print_time)
 		{
 		if (!bio_pair)
@@ -2059,15 +2088,7 @@
 		}
 
 #ifndef OPENSSL_NO_X509_VERIFY
-# ifdef OPENSSL_FIPS
-	if(s->version == TLS1_VERSION)
-		FIPS_allow_md5(1);
-# endif
 	ok = X509_verify_cert(ctx);
-# ifdef OPENSSL_FIPS
-	if(s->version == TLS1_VERSION)
-		FIPS_allow_md5(0);
-# endif
 #endif
 
 	if (cb_arg->proxy_auth)
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index ed5a4a7..7cb3e29 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -111,10 +111,15 @@
 
 #include <stdio.h>
 #include "ssl_locl.h"
+#ifndef OPENSSL_NO_COMP
 #include <openssl/comp.h>
+#endif
 #include <openssl/evp.h>
 #include <openssl/hmac.h>
 #include <openssl/md5.h>
+#ifdef KSSL_DEBUG
+#include <openssl/des.h>
+#endif
 
 static void tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
 			int sec_len, unsigned char *seed, int seed_len,
@@ -131,6 +136,8 @@
 
 	HMAC_CTX_init(&ctx);
 	HMAC_CTX_init(&ctx_tmp);
+	HMAC_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+	HMAC_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
 	HMAC_Init_ex(&ctx,sec,sec_len,md, NULL);
 	HMAC_Init_ex(&ctx_tmp,sec,sec_len,md, NULL);
 	HMAC_Update(&ctx,seed,seed_len);
@@ -249,15 +256,15 @@
 #ifdef KSSL_DEBUG
 	printf("tls1_change_cipher_state(which= %d) w/\n", which);
 	printf("\talg= %ld, comp= %p\n", s->s3->tmp.new_cipher->algorithms,
-                comp);
-	printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c);
+                (void *)comp);
+	printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", (void *)c);
 	printf("\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n",
                 c->nid,c->block_size,c->key_len,c->iv_len);
 	printf("\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length);
 	{
-        int i;
-        for (i=0; i<s->s3->tmp.key_block_length; i++)
-		printf("%02x", key_block[i]);  printf("\n");
+        int ki;
+        for (ki=0; ki<s->s3->tmp.key_block_length; ki++)
+		printf("%02x", key_block[ki]);  printf("\n");
         }
 #endif	/* KSSL_DEBUG */
 
@@ -413,11 +420,13 @@
 	s->session->key_arg_length=0;
 #ifdef KSSL_DEBUG
 	{
-        int i;
+        int ki;
 	printf("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n");
-	printf("\tkey= "); for (i=0; i<c->key_len; i++) printf("%02x", key[i]);
+	printf("\tkey= ");
+	for (ki=0; ki<c->key_len; ki++) printf("%02x", key[ki]);
 	printf("\n");
-	printf("\t iv= "); for (i=0; i<c->iv_len; i++) printf("%02x", iv[i]);
+	printf("\t iv= ");
+	for (ki=0; ki<c->iv_len; ki++) printf("%02x", iv[ki]);
 	printf("\n");
 	}
 #endif	/* KSSL_DEBUG */
@@ -590,10 +599,11 @@
 		{
                 unsigned long ui;
 		printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
-                        ds,rec->data,rec->input,l);
-		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
+                        (void *)ds,rec->data,rec->input,l);
+		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%ld %ld], %d iv_len\n",
                         ds->buf_len, ds->cipher->key_len,
-                        DES_KEY_SZ, DES_SCHEDULE_SZ,
+                        (unsigned long)DES_KEY_SZ,
+			(unsigned long)DES_SCHEDULE_SZ,
                         ds->cipher->iv_len);
 		printf("\t\tIV: ");
 		for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
@@ -618,10 +628,10 @@
 
 #ifdef KSSL_DEBUG
 		{
-                unsigned long i;
+                unsigned long ki;
                 printf("\trec->data=");
-		for (i=0; i<l; i++)
-                        printf(" %02x", rec->data[i]);  printf("\n");
+		for (ki=0; ki<l; i++)
+                        printf(" %02x", rec->data[ki]);  printf("\n");
                 }
 #endif	/* KSSL_DEBUG */
 
@@ -805,7 +815,7 @@
 	unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH];
 
 #ifdef KSSL_DEBUG
-	printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len);
+	printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", (void *)s,out, p,len);
 #endif	/* KSSL_DEBUG */
 
 	/* Setup the stuff to munge */
@@ -852,8 +862,10 @@
 	case SSL_AD_INTERNAL_ERROR:	return(TLS1_AD_INTERNAL_ERROR);
 	case SSL_AD_USER_CANCELLED:	return(TLS1_AD_USER_CANCELLED);
 	case SSL_AD_NO_RENEGOTIATION:	return(TLS1_AD_NO_RENEGOTIATION);
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
 	case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return 
 					  (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
+#endif
 	default:			return(-1);
 		}
 	}
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 35f04af..9ce7269 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -734,6 +734,13 @@
 	/* Point after session ID in client hello */
 	const unsigned char *p = session_id + len;
 	unsigned short i;
+
+	/* If tickets disabled behave as if no ticket present
+ 	 * to permit stateful resumption.
+ 	 */
+	if (SSL_get_options(s) & SSL_OP_NO_TICKET)
+		return 1;
+
 	if ((s->version <= SSL3_VERSION) || !limit)
 		return 1;
 	if (p >= limit)
@@ -761,12 +768,7 @@
 			return 1;
 		if (type == TLSEXT_TYPE_session_ticket)
 			{
-			/* If tickets disabled indicate cache miss which will
- 			 * trigger a full handshake
- 			 */
-			if (SSL_get_options(s) & SSL_OP_NO_TICKET)
-				return 0;
-			/* If zero length not client will accept a ticket
+			/* If zero length note client will accept a ticket
  			 * and indicate cache miss to trigger full handshake
  			 */
 			if (size == 0)